@nethesis/phone-island 0.15.9 → 0.15.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/App.js +1 -1
- package/dist/App.js.map +1 -1
- package/dist/components/Socket.js +1 -1
- package/dist/components/Socket.js.map +1 -1
- package/dist/components/WebRTC.js +1 -1
- package/dist/components/WebRTC.js.map +1 -1
- package/dist/lib/devices/devices.js +1 -1
- package/dist/lib/devices/devices.js.map +1 -1
- package/package.json +1 -1
package/dist/App.js
CHANGED
|
@@ -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"),t=require("./components/Events.js"),s=require("./components/Socket.js"),i=require("./components/WebRTC.js"),o=require("./components/Island.js"),a=require("./components/RestAPI.js"),r=require("./utils/customHooks/useEventListener.js"),l=require("./utils/genericFunctions/eventDispatch.js"),u=require("./utils/genericFunctions/localStorage.js"),d=require("./store/index.js"),c=require("./services/user.js");require("./node_modules/react-redux/es/index.js"),require("./node_modules/@fortawesome/react-fontawesome/index.es.js"),require("./node_modules/i18next/dist/esm/i18next.js"),require("./node_modules/react-tooltip/dist/react-tooltip.min.mjs.js");var p=require("./node_modules/js-base64/base64.mjs.js"),h=require("./workers/wake_up.js"),v=require("./lib/i18n.js");require("./node_modules/react-tooltip/dist/react-tooltip.min.css.js");var f=require("./lib/webrtc/messages.js"),g=require("./lib/darkTheme.js"),m=require("./utils/genericFunctions/isEmpty.js"),E=require("./utils/genericFunctions/checkConnection.js"),I=require("./utils/genericFunctions/isBackCallVisible.js"),L=require("./lib/phone/trunk.js"),S=require("./node_modules/react-redux/es/components/Provider.js");function w(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}require("./node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js"),require("./node_modules/react-redux/node_modules/react-is/index.js"),require("./node_modules/react-redux/es/components/Context.js");var b=w(n),U=function(w){var U=w.dataConfig,y=w.showAlways,D=void 0!==y&&y,j=w.uaType,q=p.Base64.atob(U||"").split(":"),k=q[0],C=q[1],_=q[2],T=q[3],x=q[4],N=q[5],A=q[6],P=n.useState(!1),V=P[0],O=P[1],R=n.useState(!1),Q=R[0],z=R[1],F=n.useState(!1),$=F[0],M=F[1];n.useEffect((function(){var e=new Worker(h.default,{type:"module"});return e.onmessage=function(e){"wakeup"===e.data&&O(!0)},function(){e.terminate()}}),[]),n.useEffect((function(){$&&Q&&(O(!1),z(!1),M(!1))}),[$,Q]),r.useEventListener("phone-island-expand",(function(){d.store.dispatch.island.toggleIsOpen(!0),l.eventDispatch("phone-island-expanded",{})})),r.useEventListener("phone-island-compress",(function(){d.store.dispatch.island.toggleIsOpen(!1),l.eventDispatch("phone-island-compressed",{})})),r.useEventListener("phone-island-call-keypad-close",(function(){d.store.dispatch.island.setIslandView("call"),l.eventDispatch("phone-island-call-keypad-closed",{})})),r.useEventListener("phone-island-call-transfer-close",(function(){d.store.dispatch.island.setIslandView("call"),l.eventDispatch("phone-island-call-transfer-closed",{})})),r.useEventListener("phone-island-recording-close",(function(){d.store.dispatch.island.setIslandView(null),l.eventDispatch("phone-island-recording-closed",{})})),r.useEventListener("phone-island-audio-player-close",(function(){d.store.dispatch.island.setIslandView(null),l.eventDispatch("phone-island-audio-player-closed",{})})),r.useEventListener("phone-island-detach",(function(e){f.detach(),l.eventDispatch("phone-island-detached",{})})),r.useEventListener("phone-island-audio-input-change",(function(e){u.setJSONItem("phone-island-audio-input-device",{deviceId:e.deviceId}),l.eventDispatch("phone-island-audio-input-changed",{})})),r.useEventListener("phone-island-video-input-change",(function(e){u.setJSONItem("phone-island-video-input-device",{deviceId:e.deviceId}),l.eventDispatch("phone-island-video-input-changed",{})}));var W=n.useState(!0),B=W[0],J=W[1],H=n.useState(!0),G=H[0],K=H[1];n.useEffect((function(){B&&(v.initI18n(),e.__awaiter(void 0,void 0,void 0,(function(){var n,t,s,i;return e.__generator(this,(function(e){switch(e.label){case 0:return e.trys.push([0,2,,3]),[4,c.getParamUrl()];case 1:return n=e.sent(),t=(null==n?void 0:n.url)||"",s=t&&""!==t.trim(),d.store.dispatch.paramUrl.setParamUrl({url:t,onlyQueues:(null==n?void 0:n.only_queues)||!1,hasValidUrl:s}),[3,3];case 2:return i=e.sent(),console.error("Error fetching URL parameter:",i),d.store.dispatch.paramUrl.setParamUrl({url:"",onlyQueues:!1,hasValidUrl:!1}),[3,3];case 3:return[2]}}))})),J(!1))}),[B]),r.useEventListener("phone-island-audio-output-change",(function(e){G||(d.store.dispatch.island.setIslandView(null),d.store.dispatch.island.toggleAvoidToShow(!0),l.eventDispatch("phone-island-call-start",{number:"*43"})),setTimeout((function(){var n=d.store.getState().player.remoteAudio;null==n||n.current.setSinkId(e.deviceId).then((function(){console.info("Default audio output device change with success!"),u.setJSONItem("phone-island-audio-output-device",{deviceId:e.deviceId}),l.eventDispatch("phone-island-audio-output-changed",{}),l.eventDispatch("phone-island-call-end",{}),d.store.dispatch.island.toggleAvoidToShow(!1)})).catch((function(e){console.error("Default audio output device change error:",e),l.eventDispatch("phone-island-call-end",{}),d.store.dispatch.island.toggleAvoidToShow(!1)}))}),500)})),r.useEventListener("phone-island-presence-change",(function(e){c.changeOperatorStatus(e),l.eventDispatch("phone-island-presence-changed",{})})),r.useEventListener("phone-island-view-changed",(function(e){var n=null==e?void 0:e.viewType;d.store.dispatch.island.setIslandView(n)}));var X=d.store.getState().player.remoteAudio;n.useEffect((function(){var e;if(G&&X){var n=null===(e=u.getJSONItem("phone-island-audio-output-device"))||void 0===e?void 0:e.deviceId;l.eventDispatch("phone-island-audio-output-change",{deviceId:n}),K(!1)}}),[G,X]),n.useEffect((function(){g.checkDarkTheme()}),[]),r.useEventListener("phone-island-theme-change",(function(e){g.setTheme(null==e?void 0:e.selectedTheme)})),r.useEventListener("phone-island-default-device-change",(function(e){d.store.dispatch.currentUser.updateCurrentDefaultDevice(null==e?void 0:e.deviceInformationObject),l.eventDispatch("phone-island-default-device-changed",{})})),r.useEventListener("phone-island-alert",(function(e){d.store.dispatch.alerts.setAlert(e.toString())})),r.useEventListener("phone-island-check-connection",(function(){E.checkInternetConnection().then((function(e){e?l.eventDispatch("phone-island-internet-connected",{}):l.eventDispatch("phone-island-internet-disconnected",{})}))})),n.useEffect((function(){var e=setInterval((function(){E.checkInternetConnection().then((function(e){e?l.eventDispatch("phone-island-internet-connected",{}):l.eventDispatch("phone-island-internet-disconnected",{})}))}),5e3);return function(){return clearInterval(e)}}),[]),r.useEventListener("phone-island-main-presence",(function(e){var n,t,s,i,o=null===(n=d.store.getState().currentUser)||void 0===n?void 0:n.username,a=d.store.getState().currentUser,r=null==a?void 0:a.mainPresence;if(void 0!==o&&""!==o&&!m.isEmpty(e[o])&&void 0!==(null===(t=e[o])||void 0===t?void 0:t.mainPresence)){var u=null===(s=e[o])||void 0===s?void 0:s.mainPresence;d.store.dispatch.currentUser.updateMainPresence(null===(i=e[o])||void 0===i?void 0:i.mainPresence),"online"===u&&"online"!==r&&l.eventDispatch("phone-island-call-ended",{})}})),r.useEventListener("phone-island-call-status",(function(){var e=d.store.getState().currentCall;console.log("Call status debug informations: ",e)}));var Y=function(e,n,t,s){var i=d.store.getState().paramUrl;if(null==i?void 0:i.hasValidUrl){var o=i.url||"";if(o){var a=d.store.getState().island.urlOpened,r=i.openParamUrlType;if(!a||"button"===r){var u=o;u.includes("$CALLER_NUMBER")&&e&&(u=u.replace(/\$CALLER_NUMBER/g,encodeURIComponent(e))),u.includes("$CALLER_NAME")&&n&&(u=u.replace(/\$CALLER_NAME/g,encodeURIComponent(n))),u.includes("$UNIQUEID")&&s&&(u=u.replace(/\$UNIQUEID/g,encodeURIComponent(s))),u.includes("$CALLED")&&t&&(u=u.replace(/\$CALLED/g,encodeURIComponent(t))),u.includes("{phone}")&&e&&(u=u.replace(/\{phone\}/g,encodeURIComponent(e)));var c=u.startsWith("http")?u:"https://".concat(u);if("mobile"!==j){var p=window.open("about:blank","_blank");p&&(p.location.href=c,d.store.dispatch.island.setUrlOpened(!0))}else l.eventDispatch("phone-island-url-parameter-opened-external",{formattedUrl:c})}}}};return r.useEventListener("phone-island-already-opened-external-page",(function(){d.store.dispatch.island.setUrlOpened(!0)})),r.useEventListener("phone-island-url-parameter-opened",(function(e){var n=d.store.getState().paramUrl;if(n.hasValidUrl&&!d.store.getState().island.urlOpened){var t=n.onlyQueues||!1,s=L.isFromTrunk(null==e?void 0:e.counterpartNum);d.store.dispatch.paramUrl.setThroughTrunk(s),"in"===(null==e?void 0:e.direction)&&(!0===t&&!0===(null==e?void 0:e.throughQueue)?Y(null==e?void 0:e.counterpartNum,null==e?void 0:e.counterpartName,null==e?void 0:e.owner,null==e?void 0:e.uniqueId):!1!==t||!0!==s&&!0!==(null==e?void 0:e.throughQueue)||Y(null==e?void 0:e.counterpartNum,null==e?void 0:e.counterpartName,null==e?void 0:e.owner,null==e?void 0:e.uniqueId))}})),r.useEventListener("phone-island-user-status",(function(){var e=d.store.getState().currentUser;console.log("User status debug informations: ",e)})),r.useEventListener("phone-island-all-users-status",(function(){var e=d.store.getState().users;console.log("Users status debug informations: ",e)})),r.useEventListener("phone-island-status",(function(){var e=d.store.getState().island;console.log("Phone island status debug informations: ",e)})),r.useEventListener("phone-island-webrtc-status",(function(){var e=d.store.getState().webrtc;console.log("Webrtc status debug informations: ",e)})),r.useEventListener("phone-island-player-status",(function(){var e=d.store.getState().player;console.log("Player status debug informations: ",e)})),r.useEventListener("phone-island-conference-status",(function(){var e=d.store.getState().conference;console.log("Webrtc status debug informations: ",e)})),r.useEventListener("phone-island-streaming-status",(function(){var e=d.store.getState().streaming;console.log("Streaming status debug informations: ",e)})),r.useEventListener("phone-island-paramurl-status",(function(){var e=d.store.getState().paramUrl;console.log("Paramurl status debug informations: ",e)})),r.useEventListener("phone-island-player-force-stop",(function(){d.store.dispatch.player.reset(),console.log("Audio player is interrupted")})),r.useEventListener("phone-island-sideview-open",(function(){d.store.dispatch.island.toggleSideViewVisible(!0),d.store.dispatch.island.setUrlOpened(!1),l.eventDispatch("phone-island-sideview-opened",{})})),r.useEventListener("phone-island-sideview-close",(function(){d.store.dispatch.island.toggleSideViewVisible(!1),l.eventDispatch("phone-island-sideview-closed",{})})),r.useEventListener("phone-island-size-change",(function(n){var t=d.store.getState().island.sideViewIsVisible,s=n.sizeInformation,i=e.__assign(e.__assign({},s),{right:t?"42px":"0px",top:I.isBackCallActive()?"40px":"0px"});l.eventDispatch("phone-island-size-changed",{sizes:i})})),r.useEventListener("phone-island-call-ended",(function(){if("online"===d.store.getState().currentUser.mainPresence){l.eventDispatch("phone-island-size-change",{sizeInformation:{width:"0px",height:"0px"}}),l.eventDispatch("phone-island-sideview-close",{}),d.store.dispatch.island.resetIslandStore(),d.store.dispatch.paramUrl.setThroughTrunk(!1)}})),r.useEventListener("phone-island-conference-list-open",(function(){d.store.dispatch.island.toggleConferenceList(!0),l.eventDispatch("phone-island-conference-list-opened",{})})),r.useEventListener("phone-island-alert-removed",(function(e){var n=d.store.getState().alerts.status.activeAlertsCount,t=d.store.getState().island,s=t.view,i=t.previousView,o=d.store.getState().conference.isActive,a=d.store.getState().alerts.data,r=d.store.getState().currentCall,u=r.incoming,c=r.outgoing,p=r.accepted,h=null==e?void 0:e.type,v=r.incoming||r.outgoing||r.accepted||""!==r.conversationId;if(!(u||c||p||n>0||"player"===s||"recorder"===s||"physicalPhoneRecorder"===s||"waitingConference"===s&&o||"transfer"===s&&o||"settings"===s&&o||"settings"===s&&("recorder"===i||"player"===i))&&0===n&&(!h||a[h]&&!a[h].active)&&!v){l.eventDispatch("phone-island-size-change",{sizeInformation:{width:"0px",height:"0px"}}),l.eventDispatch("phone-island-sideview-close",{}),d.store.dispatch.island.resetIslandStore()}})),r.useEventListener("phone-island-conference-list-close",(function(){d.store.dispatch.island.toggleConferenceList(!1),l.eventDispatch("phone-island-conference-list-closed",{})})),r.useEventListener("phone-island-conversations",(function(e){var n,t=Object.keys(e)[0];if(t===(null===(n=d.store.getState().currentUser)||void 0===n?void 0:n.username)){var s=e[t].conversations,i=d.store.getState().paramUrl,o=d.store.getState().island.urlOpened;if(!i.hasValidUrl||o)return;if("answered"===i.openParamUrlType&&s&&Object.keys(s).length>0){var a=s[Object.keys(s)[0]];if((null==a?void 0:a.connected)&&"in"===(null==a?void 0:a.direction)){var r=i.onlyQueues||!1,l=L.isFromTrunk(a.counterpartNum);d.store.dispatch.paramUrl.setThroughTrunk(l),!0===r&&!0===(null==a?void 0:a.throughQueue)?Y(a.counterpartNum,a.counterpartName,a.owner,a.uniqueId):!1!==r||!0!==l&&!0!==(null==a?void 0:a.throughQueue)||Y(a.counterpartNum,a.counterpartName,a.owner,a.uniqueId)}}}})),b.default.createElement(b.default.Fragment,null,b.default.createElement(S.default,{store:d.store},b.default.createElement(i.WebRTC,{hostName:k,sipExten:T,sipSecret:x,sipHost:N,sipPort:A,reload:V,reloadedCallback:function(){return z(!0)},uaType:j},b.default.createElement(a.RestAPI,{hostName:k,username:C,authToken:_},b.default.createElement(s.Socket,{hostName:k,username:C,authToken:_,reload:V,reloadedCallback:function(){return M(!0)},uaType:j},b.default.createElement(t.Events,{sipHost:N},b.default.createElement(o.Island,{showAlways:D,uaType:j})))))))};U.displayName="PhoneIsland",exports.PhoneIsland=U;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("./node_modules/tslib/tslib.es6.js"),t=require("react"),n=require("./components/Events.js"),i=require("./components/Socket.js"),s=require("./components/WebRTC.js"),a=require("./components/Island.js"),r=require("./components/RestAPI.js"),o=require("./utils/customHooks/useEventListener.js"),u=require("./utils/genericFunctions/eventDispatch.js"),c=require("./utils/genericFunctions/localStorage.js"),d=require("./store/index.js"),l=require("./services/user.js");require("./node_modules/react-redux/es/index.js"),require("./node_modules/@fortawesome/react-fontawesome/index.es.js"),require("./node_modules/i18next/dist/esm/i18next.js"),require("./node_modules/react-tooltip/dist/react-tooltip.min.mjs.js");var v=require("./node_modules/js-base64/base64.mjs.js"),p=require("./workers/wake_up.js"),h=require("./lib/i18n.js");require("./node_modules/react-tooltip/dist/react-tooltip.min.css.js");var f=require("./lib/webrtc/messages.js"),m=require("./lib/darkTheme.js"),g=require("./utils/genericFunctions/isEmpty.js"),I=require("./utils/genericFunctions/checkConnection.js"),w=require("./utils/genericFunctions/isBackCallVisible.js"),b=require("./lib/phone/trunk.js"),E=require("./node_modules/react-redux/es/components/Provider.js");function D(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}require("./node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js"),require("./node_modules/react-redux/node_modules/react-is/index.js"),require("./node_modules/react-redux/es/components/Context.js");var _=D(t),y=function(D){var y=D.dataConfig,S=D.showAlways,k=void 0!==S&&S,L=D.uaType,U=v.Base64.atob(y||"").split(":"),j=U[0],q=U[1],C=U[2],N=U[3],O=U[4],T=U[5],x=U[6],A=t.useState(!1),P=A[0],V=A[1],R=t.useState(!1),F=R[0],J=R[1],Q=t.useState(!1),z=Q[0],$=Q[1];t.useEffect((function(){var e=new Worker(p.default,{type:"module"});return e.onmessage=function(e){"wakeup"===e.data&&V(!0)},function(){e.terminate()}}),[]),t.useEffect((function(){z&&F&&(V(!1),J(!1),$(!1))}),[z,F]),o.useEventListener("phone-island-expand",(function(){d.store.dispatch.island.toggleIsOpen(!0),u.eventDispatch("phone-island-expanded",{})})),o.useEventListener("phone-island-compress",(function(){d.store.dispatch.island.toggleIsOpen(!1),u.eventDispatch("phone-island-compressed",{})})),o.useEventListener("phone-island-call-keypad-close",(function(){d.store.dispatch.island.setIslandView("call"),u.eventDispatch("phone-island-call-keypad-closed",{})})),o.useEventListener("phone-island-call-transfer-close",(function(){d.store.dispatch.island.setIslandView("call"),u.eventDispatch("phone-island-call-transfer-closed",{})})),o.useEventListener("phone-island-recording-close",(function(){d.store.dispatch.island.setIslandView(null),u.eventDispatch("phone-island-recording-closed",{})})),o.useEventListener("phone-island-audio-player-close",(function(){d.store.dispatch.island.setIslandView(null),u.eventDispatch("phone-island-audio-player-closed",{})})),o.useEventListener("phone-island-detach",(function(e){f.detach(),u.eventDispatch("phone-island-detached",{})})),o.useEventListener("phone-island-audio-input-change",(function(t){return e.__awaiter(void 0,void 0,void 0,(function(){var n;return e.__generator(this,(function(e){switch(e.label){case 0:return(n=t.deviceId)&&"default"!==n?[4,X(n)]:[3,3];case 1:return e.sent()?[3,3]:(console.warn("Audio input device ".concat(n," not available, falling back to default device")),[4,Y()]);case 2:n=e.sent(),e.label=3;case 3:return c.setJSONItem("phone-island-audio-input-device",{deviceId:n}),u.eventDispatch("phone-island-audio-input-changed",{}),n!==t.deviceId&&console.info("Audio input device changed from ".concat(t.deviceId," to ").concat(n," (fallback)")),[2]}}))}))})),o.useEventListener("phone-island-video-input-change",(function(t){return e.__awaiter(void 0,void 0,void 0,(function(){var n;return e.__generator(this,(function(e){switch(e.label){case 0:return(n=t.deviceId)&&"default"!==n?[4,Z(n)]:[3,3];case 1:return e.sent()?[3,3]:(console.warn("Video input device ".concat(n," not available, falling back to default device")),[4,ee()]);case 2:n=e.sent(),e.label=3;case 3:return c.setJSONItem("phone-island-video-input-device",{deviceId:n}),u.eventDispatch("phone-island-video-input-changed",{}),n!==t.deviceId&&console.info("Video input device changed from ".concat(t.deviceId," to ").concat(n," (fallback)")),[2]}}))}))}));var M=t.useState(!0),W=M[0],B=M[1],H=t.useState(!0),G=H[0],K=H[1];t.useEffect((function(){W&&(h.initI18n(),e.__awaiter(void 0,void 0,void 0,(function(){var t,n,i,s;return e.__generator(this,(function(e){switch(e.label){case 0:return e.trys.push([0,2,,3]),[4,l.getParamUrl()];case 1:return t=e.sent(),n=(null==t?void 0:t.url)||"",i=n&&""!==n.trim(),d.store.dispatch.paramUrl.setParamUrl({url:n,onlyQueues:(null==t?void 0:t.only_queues)||!1,hasValidUrl:i}),[3,3];case 2:return s=e.sent(),console.error("Error fetching URL parameter:",s),d.store.dispatch.paramUrl.setParamUrl({url:"",onlyQueues:!1,hasValidUrl:!1}),[3,3];case 3:return[2]}}))})),B(!1))}),[W]);var X=function(t){return e.__awaiter(void 0,void 0,void 0,(function(){var n,i;return e.__generator(this,(function(e){switch(e.label){case 0:return e.trys.push([0,2,,3]),navigator.mediaDevices&&navigator.mediaDevices.enumerateDevices?[4,navigator.mediaDevices.enumerateDevices()]:[2,!1];case 1:return n=e.sent(),[2,n.filter((function(e){return"audioinput"===e.kind})).some((function(e){return e.deviceId===t}))];case 2:return i=e.sent(),console.warn("Error checking audio input device availability:",i),[2,!1];case 3:return[2]}}))}))},Y=function(){return e.__awaiter(void 0,void 0,void 0,(function(){var t,n,i,s;return e.__generator(this,(function(e){switch(e.label){case 0:return e.trys.push([0,2,,3]),navigator.mediaDevices&&navigator.mediaDevices.enumerateDevices?[4,navigator.mediaDevices.enumerateDevices()]:[2,"default"];case 1:return t=e.sent(),n=t.filter((function(e){return"audioinput"===e.kind})),[2,(i=n.find((function(e){return"default"===e.deviceId||""===e.deviceId}))||n[0])?i.deviceId:"default"];case 2:return s=e.sent(),console.warn("Error getting default audio input device:",s),[2,"default"];case 3:return[2]}}))}))},Z=function(t){return e.__awaiter(void 0,void 0,void 0,(function(){var n,i;return e.__generator(this,(function(e){switch(e.label){case 0:return e.trys.push([0,2,,3]),navigator.mediaDevices&&navigator.mediaDevices.enumerateDevices?[4,navigator.mediaDevices.enumerateDevices()]:[2,!1];case 1:return n=e.sent(),[2,n.filter((function(e){return"videoinput"===e.kind})).some((function(e){return e.deviceId===t}))];case 2:return i=e.sent(),console.warn("Error checking video input device availability:",i),[2,!1];case 3:return[2]}}))}))},ee=function(){return e.__awaiter(void 0,void 0,void 0,(function(){var t,n,i,s;return e.__generator(this,(function(e){switch(e.label){case 0:return e.trys.push([0,2,,3]),navigator.mediaDevices&&navigator.mediaDevices.enumerateDevices?[4,navigator.mediaDevices.enumerateDevices()]:[2,"default"];case 1:return t=e.sent(),n=t.filter((function(e){return"videoinput"===e.kind})),[2,(i=n.find((function(e){return"default"===e.deviceId||""===e.deviceId}))||n[0])?i.deviceId:"default"];case 2:return s=e.sent(),console.warn("Error getting default video input device:",s),[2,"default"];case 3:return[2]}}))}))};o.useEventListener("phone-island-audio-output-change",(function(t){e.__awaiter(void 0,void 0,void 0,(function(){var n,i,s,a,r,o,l,v,p;return e.__generator(this,(function(h){switch(h.label){case 0:return(null==(n=d.store.getState().player.remoteAudio)?void 0:n.current)?(i=t.deviceId)&&"default"!==i?[4,(f=i,e.__awaiter(void 0,void 0,void 0,(function(){var t;return e.__generator(this,(function(e){switch(e.label){case 0:return e.trys.push([0,2,,3]),navigator.mediaDevices&&navigator.mediaDevices.enumerateDevices?[4,navigator.mediaDevices.enumerateDevices()]:[2,!1];case 1:return[2,e.sent().filter((function(e){return"audiooutput"===e.kind})).some((function(e){return e.deviceId===f}))];case 2:return t=e.sent(),console.warn("Error checking device availability:",t),[2,!1];case 3:return[2]}}))})))]:[3,3]:(console.warn("Remote audio element not available"),[2]);case 1:return h.sent()?[3,3]:(console.warn("Audio output device ".concat(i," not available, falling back to default device")),[4,e.__awaiter(void 0,void 0,void 0,(function(){var t,n,i,s;return e.__generator(this,(function(e){switch(e.label){case 0:return e.trys.push([0,2,,3]),navigator.mediaDevices&&navigator.mediaDevices.enumerateDevices?[4,navigator.mediaDevices.enumerateDevices()]:[2,"default"];case 1:return t=e.sent(),n=t.filter((function(e){return"audiooutput"===e.kind})),[2,(i=n.find((function(e){return"default"===e.deviceId||""===e.deviceId}))||n[0])?i.deviceId:"default"];case 2:return s=e.sent(),console.warn("Error getting default device:",s),[2,"default"];case 3:return[2]}}))}))]);case 2:i=h.sent(),c.setJSONItem("phone-island-audio-output-device",{deviceId:i}),h.label=3;case 3:return h.trys.push([3,5,,15]),[4,n.current.setSinkId(i)];case 4:return h.sent(),console.info("Default audio output device changed successfully!"),c.setJSONItem("phone-island-audio-output-device",{deviceId:i}),u.eventDispatch("phone-island-audio-output-changed",{}),[3,15];case 5:s=h.sent(),console.log("Direct setSinkId failed, trying with temporary stream:",s),h.label=6;case 6:return h.trys.push([6,7,,14]),a=new(window.AudioContext||window.webkitAudioContext),r=a.createOscillator(),o=a.createGain(),r.frequency.setValueAtTime(440,a.currentTime),o.gain.setValueAtTime(0,a.currentTime),r.connect(o),l=a.createMediaStreamDestination(),o.connect(l),n.current.srcObject=l.stream,r.start(),setTimeout((function(){return e.__awaiter(void 0,void 0,void 0,(function(){var t,s;return e.__generator(this,(function(e){switch(e.label){case 0:return e.trys.push([0,2,,7]),[4,n.current.setSinkId(i)];case 1:return e.sent(),console.info("Default audio output device changed successfully with temporary stream!"),r.stop(),a.close(),n.current.srcObject=null,c.setJSONItem("phone-island-audio-output-device",{deviceId:i}),u.eventDispatch("phone-island-audio-output-changed",{}),[3,7];case 2:if(t=e.sent(),console.error("Final setSinkId attempt failed:",t),r.stop(),a.close(),n.current.srcObject=null,"default"===i)return[3,6];console.log("Trying fallback to default device"),e.label=3;case 3:return e.trys.push([3,5,,6]),[4,n.current.setSinkId("default")];case 4:return e.sent(),c.setJSONItem("phone-island-audio-output-device",{deviceId:"default"}),console.info("Fallback to default audio device successful"),[3,6];case 5:return s=e.sent(),console.error("Even default device failed:",s),[3,6];case 6:return c.setJSONItem("phone-island-audio-output-device",{deviceId:i}),u.eventDispatch("phone-island-audio-output-changed",{}),[3,7];case 7:return[2]}}))}))}),100),[3,14];case 7:if(v=h.sent(),console.error("Failed to create temporary audio stream:",v),"default"===i)return[3,12];h.label=8;case 8:return h.trys.push([8,10,,11]),[4,n.current.setSinkId("default")];case 9:return h.sent(),c.setJSONItem("phone-island-audio-output-device",{deviceId:"default"}),console.info("Emergency fallback to default audio device successful"),[3,11];case 10:return p=h.sent(),console.error("Emergency fallback to default device failed:",p),c.setJSONItem("phone-island-audio-output-device",{deviceId:i}),[3,11];case 11:return[3,13];case 12:c.setJSONItem("phone-island-audio-output-device",{deviceId:i}),h.label=13;case 13:return u.eventDispatch("phone-island-audio-output-changed",{}),[3,14];case 14:return[3,15];case 15:return[2]}var f}))}))})),o.useEventListener("phone-island-presence-change",(function(e){l.changeOperatorStatus(e),u.eventDispatch("phone-island-presence-changed",{})})),o.useEventListener("phone-island-view-changed",(function(e){var t=null==e?void 0:e.viewType;d.store.dispatch.island.setIslandView(t)}));var te=d.store.getState().player.remoteAudio;t.useEffect((function(){var e;if(G&&te){var t=null===(e=c.getJSONItem("phone-island-audio-output-device"))||void 0===e?void 0:e.deviceId;u.eventDispatch("phone-island-audio-output-change",{deviceId:t}),K(!1)}}),[G,te]),t.useEffect((function(){m.checkDarkTheme()}),[]),o.useEventListener("phone-island-theme-change",(function(e){m.setTheme(null==e?void 0:e.selectedTheme)})),o.useEventListener("phone-island-default-device-change",(function(e){d.store.dispatch.currentUser.updateCurrentDefaultDevice(null==e?void 0:e.deviceInformationObject),u.eventDispatch("phone-island-default-device-changed",{})})),o.useEventListener("phone-island-alert",(function(e){d.store.dispatch.alerts.setAlert(e.toString())})),o.useEventListener("phone-island-check-connection",(function(){I.checkInternetConnection().then((function(e){e?u.eventDispatch("phone-island-internet-connected",{}):u.eventDispatch("phone-island-internet-disconnected",{})}))})),t.useEffect((function(){var e=setInterval((function(){I.checkInternetConnection().then((function(e){e?u.eventDispatch("phone-island-internet-connected",{}):u.eventDispatch("phone-island-internet-disconnected",{})}))}),5e3);return function(){return clearInterval(e)}}),[]),o.useEventListener("phone-island-main-presence",(function(e){var t,n,i,s,a=null===(t=d.store.getState().currentUser)||void 0===t?void 0:t.username,r=d.store.getState().currentUser,o=null==r?void 0:r.mainPresence;if(void 0!==a&&""!==a&&!g.isEmpty(e[a])&&void 0!==(null===(n=e[a])||void 0===n?void 0:n.mainPresence)){var c=null===(i=e[a])||void 0===i?void 0:i.mainPresence;d.store.dispatch.currentUser.updateMainPresence(null===(s=e[a])||void 0===s?void 0:s.mainPresence),"online"===c&&"online"!==o&&u.eventDispatch("phone-island-call-ended",{})}})),o.useEventListener("phone-island-call-status",(function(){var e=d.store.getState().currentCall;console.log("Call status debug informations: ",e)}));var ne=function(e,t,n,i){var s=d.store.getState().paramUrl;if(null==s?void 0:s.hasValidUrl){var a=s.url||"";if(a){var r=d.store.getState().island.urlOpened,o=s.openParamUrlType;if(!r||"button"===o){var c=a;c.includes("$CALLER_NUMBER")&&e&&(c=c.replace(/\$CALLER_NUMBER/g,encodeURIComponent(e))),c.includes("$CALLER_NAME")&&t&&(c=c.replace(/\$CALLER_NAME/g,encodeURIComponent(t))),c.includes("$UNIQUEID")&&i&&(c=c.replace(/\$UNIQUEID/g,encodeURIComponent(i))),c.includes("$CALLED")&&n&&(c=c.replace(/\$CALLED/g,encodeURIComponent(n))),c.includes("{phone}")&&e&&(c=c.replace(/\{phone\}/g,encodeURIComponent(e)));var l=c.startsWith("http")?c:"https://".concat(c);if("mobile"!==L){var v=window.open("about:blank","_blank");v&&(v.location.href=l,d.store.dispatch.island.setUrlOpened(!0))}else u.eventDispatch("phone-island-url-parameter-opened-external",{formattedUrl:l})}}}};return o.useEventListener("phone-island-already-opened-external-page",(function(){d.store.dispatch.island.setUrlOpened(!0)})),o.useEventListener("phone-island-url-parameter-opened",(function(e){var t=d.store.getState().paramUrl;if(t.hasValidUrl&&!d.store.getState().island.urlOpened){var n=t.onlyQueues||!1,i=b.isFromTrunk(null==e?void 0:e.counterpartNum);d.store.dispatch.paramUrl.setThroughTrunk(i),"in"===(null==e?void 0:e.direction)&&(!0===n&&!0===(null==e?void 0:e.throughQueue)?ne(null==e?void 0:e.counterpartNum,null==e?void 0:e.counterpartName,null==e?void 0:e.owner,null==e?void 0:e.uniqueId):!1!==n||!0!==i&&!0!==(null==e?void 0:e.throughQueue)||ne(null==e?void 0:e.counterpartNum,null==e?void 0:e.counterpartName,null==e?void 0:e.owner,null==e?void 0:e.uniqueId))}})),o.useEventListener("phone-island-user-status",(function(){var e=d.store.getState().currentUser;console.log("User status debug informations: ",e)})),o.useEventListener("phone-island-all-users-status",(function(){var e=d.store.getState().users;console.log("Users status debug informations: ",e)})),o.useEventListener("phone-island-status",(function(){var e=d.store.getState().island;console.log("Phone island status debug informations: ",e)})),o.useEventListener("phone-island-webrtc-status",(function(){var e=d.store.getState().webrtc;console.log("Webrtc status debug informations: ",e)})),o.useEventListener("phone-island-player-status",(function(){var e=d.store.getState().player;console.log("Player status debug informations: ",e)})),o.useEventListener("phone-island-conference-status",(function(){var e=d.store.getState().conference;console.log("Webrtc status debug informations: ",e)})),o.useEventListener("phone-island-streaming-status",(function(){var e=d.store.getState().streaming;console.log("Streaming status debug informations: ",e)})),o.useEventListener("phone-island-paramurl-status",(function(){var e=d.store.getState().paramUrl;console.log("Paramurl status debug informations: ",e)})),o.useEventListener("phone-island-player-force-stop",(function(){d.store.dispatch.player.reset(),console.log("Audio player is interrupted")})),o.useEventListener("phone-island-sideview-open",(function(){d.store.dispatch.island.toggleSideViewVisible(!0),d.store.dispatch.island.setUrlOpened(!1),u.eventDispatch("phone-island-sideview-opened",{})})),o.useEventListener("phone-island-sideview-close",(function(){d.store.dispatch.island.toggleSideViewVisible(!1),u.eventDispatch("phone-island-sideview-closed",{})})),o.useEventListener("phone-island-size-change",(function(t){var n=d.store.getState().island.sideViewIsVisible,i=t.sizeInformation,s=e.__assign(e.__assign({},i),{right:n?"42px":"0px",top:w.isBackCallActive()?"40px":"0px"});u.eventDispatch("phone-island-size-changed",{sizes:s})})),o.useEventListener("phone-island-call-ended",(function(){if("online"===d.store.getState().currentUser.mainPresence){u.eventDispatch("phone-island-size-change",{sizeInformation:{width:"0px",height:"0px"}}),u.eventDispatch("phone-island-sideview-close",{}),d.store.dispatch.island.resetIslandStore(),d.store.dispatch.paramUrl.setThroughTrunk(!1)}})),o.useEventListener("phone-island-conference-list-open",(function(){d.store.dispatch.island.toggleConferenceList(!0),u.eventDispatch("phone-island-conference-list-opened",{})})),o.useEventListener("phone-island-alert-removed",(function(e){var t=d.store.getState().alerts.status.activeAlertsCount,n=d.store.getState().island,i=n.view,s=n.previousView,a=d.store.getState().conference.isActive,r=d.store.getState().alerts.data,o=d.store.getState().currentCall,c=o.incoming,l=o.outgoing,v=o.accepted,p=null==e?void 0:e.type,h=o.incoming||o.outgoing||o.accepted||""!==o.conversationId;if(!(c||l||v||t>0||"player"===i||"recorder"===i||"physicalPhoneRecorder"===i||"waitingConference"===i&&a||"transfer"===i&&a||"settings"===i&&a||"settings"===i&&("recorder"===s||"player"===s))&&0===t&&(!p||r[p]&&!r[p].active)&&!h){u.eventDispatch("phone-island-size-change",{sizeInformation:{width:"0px",height:"0px"}}),u.eventDispatch("phone-island-sideview-close",{}),d.store.dispatch.island.resetIslandStore()}})),o.useEventListener("phone-island-conference-list-close",(function(){d.store.dispatch.island.toggleConferenceList(!1),u.eventDispatch("phone-island-conference-list-closed",{})})),o.useEventListener("phone-island-conversations",(function(e){var t,n=Object.keys(e)[0];if(n===(null===(t=d.store.getState().currentUser)||void 0===t?void 0:t.username)){var i=e[n].conversations,s=d.store.getState().paramUrl,a=d.store.getState().island.urlOpened;if(!s.hasValidUrl||a)return;if("answered"===s.openParamUrlType&&i&&Object.keys(i).length>0){var r=i[Object.keys(i)[0]];if((null==r?void 0:r.connected)&&"in"===(null==r?void 0:r.direction)){var o=s.onlyQueues||!1,u=b.isFromTrunk(r.counterpartNum);d.store.dispatch.paramUrl.setThroughTrunk(u),!0===o&&!0===(null==r?void 0:r.throughQueue)?ne(r.counterpartNum,r.counterpartName,r.owner,r.uniqueId):!1!==o||!0!==u&&!0!==(null==r?void 0:r.throughQueue)||ne(r.counterpartNum,r.counterpartName,r.owner,r.uniqueId)}}}})),_.default.createElement(_.default.Fragment,null,_.default.createElement(E.default,{store:d.store},_.default.createElement(s.WebRTC,{hostName:j,sipExten:N,sipSecret:O,sipHost:T,sipPort:x,reload:P,reloadedCallback:function(){return J(!0)},uaType:L},_.default.createElement(r.RestAPI,{hostName:j,username:q,authToken:C},_.default.createElement(i.Socket,{hostName:j,username:q,authToken:C,reload:P,reloadedCallback:function(){return $(!0)},uaType:L},_.default.createElement(n.Events,{sipHost:T},_.default.createElement(a.Island,{showAlways:k,uaType:L})))))))};y.displayName="PhoneIsland",exports.PhoneIsland=y;
|
|
2
2
|
//# sourceMappingURL=App.js.map
|
package/dist/App.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"App.js","sources":["../src/App.tsx"],"sourcesContent":["import React, { type FC, useState, useEffect } from 'react'\nimport { Events, Socket, WebRTC, Island, RestAPI } from './components'\nimport { Provider } from 'react-redux'\nimport { store } from './store'\nimport { Base64 } from 'js-base64'\nimport wakeUpWorker from './workers/wake_up'\nimport { initI18n } from './lib/i18n'\n\nimport 'react-tooltip/dist/react-tooltip.css'\nimport { useEventListener, eventDispatch, setJSONItem, getJSONItem } from './utils'\nimport { detach } from './lib/webrtc/messages'\nimport { checkDarkTheme, setTheme } from './lib/darkTheme'\nimport { changeOperatorStatus } from './services/user'\nimport { getParamUrl } from './services/user'\nimport { isEmpty } from './utils/genericFunctions/isEmpty'\nimport { checkInternetConnection } from './utils/genericFunctions/checkConnection'\nimport { isBackCallActive } from './utils/genericFunctions/isBackCallVisible'\nimport { isFromTrunk } from './lib/user/extensions'\n\ninterface PhoneIslandProps {\n dataConfig: string\n showAlways?: boolean\n uaType: string\n}\n\ninterface DeviceInputOutputTypes {\n deviceId: string\n}\n\nexport const PhoneIsland: FC<PhoneIslandProps> = ({\n dataConfig,\n showAlways = false,\n uaType,\n}: PhoneIslandProps) => {\n const CONFIG: string[] = Base64.atob(dataConfig || '').split(':')\n const HOST_NAME: string = CONFIG[0]\n const USERNAME: string = CONFIG[1]\n const AUTH_TOKEN: string = CONFIG[2]\n const SIP_EXTEN: string = CONFIG[3]\n const SIP_SECRET: string = CONFIG[4]\n const SIP_HOST: string = CONFIG[5]\n const SIP_PORT: string = CONFIG[6]\n\n // Initialize the state to manage the reload events\n const [reload, setReload] = useState<boolean>(false)\n const [reloadedWebRTC, setReloadedWebRTC] = useState<boolean>(false)\n const [reloadedSocket, setReloadedSocket] = useState<boolean>(false)\n\n useEffect(() => {\n const worker = new Worker(wakeUpWorker, { type: 'module' })\n worker.onmessage = (event: MessageEvent<string>) => {\n // Handle wakeup message\n if (event.data === 'wakeup') {\n setReload(true)\n }\n }\n\n return () => {\n worker.terminate()\n }\n }, [])\n\n useEffect(() => {\n if (reloadedSocket && reloadedWebRTC) {\n setReload(false)\n setReloadedWebRTC(false)\n setReloadedSocket(false)\n }\n }, [reloadedSocket, reloadedWebRTC])\n\n useEventListener('phone-island-expand', () => {\n store.dispatch.island.toggleIsOpen(true)\n eventDispatch('phone-island-expanded', {})\n })\n useEventListener('phone-island-compress', () => {\n store.dispatch.island.toggleIsOpen(false)\n eventDispatch('phone-island-compressed', {})\n })\n\n useEventListener('phone-island-call-keypad-close', () => {\n store.dispatch.island.setIslandView('call')\n eventDispatch('phone-island-call-keypad-closed', {})\n })\n useEventListener('phone-island-call-transfer-close', () => {\n store.dispatch.island.setIslandView('call')\n eventDispatch('phone-island-call-transfer-closed', {})\n })\n useEventListener('phone-island-recording-close', () => {\n store.dispatch.island.setIslandView(null)\n eventDispatch('phone-island-recording-closed', {})\n })\n useEventListener('phone-island-audio-player-close', () => {\n store.dispatch.island.setIslandView(null)\n eventDispatch('phone-island-audio-player-closed', {})\n })\n\n useEventListener('phone-island-detach', (data) => {\n detach()\n eventDispatch('phone-island-detached', {})\n })\n\n useEventListener('phone-island-audio-input-change', (data: DeviceInputOutputTypes) => {\n setJSONItem('phone-island-audio-input-device', { deviceId: data.deviceId })\n eventDispatch('phone-island-audio-input-changed', {})\n })\n\n useEventListener('phone-island-video-input-change', (data: DeviceInputOutputTypes) => {\n setJSONItem('phone-island-video-input-device', { deviceId: data.deviceId })\n eventDispatch('phone-island-video-input-changed', {})\n })\n\n const [firstRender, setFirstRender] = useState(true)\n const [firstAudioOutputInit, setFirstAudioOutputInit] = useState(true)\n\n // Initialize application on first render\n useEffect(() => {\n const initParamUrl = async () => {\n try {\n const paramUrlResponse: any = await getParamUrl()\n const url = paramUrlResponse?.url || ''\n const isValid = url && url.trim() !== ''\n\n // Save data inside the store\n store.dispatch.paramUrl.setParamUrl({\n url: url,\n onlyQueues: paramUrlResponse?.only_queues || false,\n hasValidUrl: isValid,\n })\n } catch (error) {\n console.error('Error fetching URL parameter:', error)\n store.dispatch.paramUrl.setParamUrl({\n url: '',\n onlyQueues: false,\n hasValidUrl: false,\n })\n }\n }\n\n if (firstRender) {\n // Initialize i18n\n initI18n()\n // Initialize param URL\n initParamUrl()\n setFirstRender(false)\n }\n }, [firstRender])\n\n useEventListener('phone-island-audio-output-change', (data: DeviceInputOutputTypes) => {\n if (!firstAudioOutputInit) {\n store.dispatch.island.setIslandView(null)\n store.dispatch.island.toggleAvoidToShow(true)\n eventDispatch('phone-island-call-start', { number: '*43' })\n }\n\n setTimeout(() => {\n const remoteAudioElement: any = store.getState().player.remoteAudio\n // set audio output\n remoteAudioElement?.current\n .setSinkId(data.deviceId)\n .then(function () {\n console.info('Default audio output device change with success!')\n // set device to localstorage\n setJSONItem('phone-island-audio-output-device', { deviceId: data.deviceId })\n\n // dispatch event\n eventDispatch('phone-island-audio-output-changed', {})\n eventDispatch('phone-island-call-end', {})\n store.dispatch.island.toggleAvoidToShow(false)\n })\n .catch(function (err) {\n console.error('Default audio output device change error:', err)\n eventDispatch('phone-island-call-end', {})\n store.dispatch.island.toggleAvoidToShow(false)\n })\n }, 500)\n })\n\n // Listen for the operator status change\n useEventListener('phone-island-presence-change', (data: any) => {\n changeOperatorStatus(data)\n eventDispatch('phone-island-presence-changed', {})\n })\n\n useEventListener('phone-island-view-changed', (data) => {\n const viewType = data?.viewType\n store.dispatch.island.setIslandView(viewType)\n })\n\n const remoteAudioElement: any = store.getState().player.remoteAudio\n\n //get output device from localstorage\n useEffect(() => {\n if (firstAudioOutputInit && remoteAudioElement) {\n const defaultAudioOutputDevice: any = getJSONItem(\n `phone-island-audio-output-device`,\n )?.deviceId\n eventDispatch('phone-island-audio-output-change', {\n deviceId: defaultAudioOutputDevice,\n })\n setFirstAudioOutputInit(false)\n }\n }, [firstAudioOutputInit, remoteAudioElement])\n\n useEffect(() => {\n checkDarkTheme()\n }, [])\n\n useEventListener('phone-island-theme-change', (theme: any) => {\n setTheme(theme?.selectedTheme)\n })\n\n useEventListener('phone-island-default-device-change', (data) => {\n store.dispatch.currentUser.updateCurrentDefaultDevice(data?.deviceInformationObject)\n eventDispatch('phone-island-default-device-changed', {})\n })\n\n useEventListener('phone-island-alert', (alertType: any) => {\n store.dispatch.alerts.setAlert(alertType.toString())\n })\n\n // Manually check if internet connection is enabled or not\n useEventListener('phone-island-check-connection', () => {\n checkInternetConnection().then((internetIsActive) => {\n if (internetIsActive) {\n eventDispatch('phone-island-internet-connected', {})\n } else {\n eventDispatch('phone-island-internet-disconnected', {})\n }\n })\n })\n\n // Check internet connection every 5 seconds\n useEffect(() => {\n const intervalId = setInterval(() => {\n checkInternetConnection().then((internetIsActive) => {\n if (internetIsActive) {\n eventDispatch('phone-island-internet-connected', {})\n } else {\n eventDispatch('phone-island-internet-disconnected', {})\n }\n })\n }, 5000)\n\n return () => clearInterval(intervalId)\n }, [])\n\n useEventListener('phone-island-main-presence', (data: any) => {\n const currentUsernameInformation: any = store.getState().currentUser?.username\n const currentUserObject: any = store.getState().currentUser\n let mainPresenceValueBeforeUpdate = currentUserObject?.mainPresence\n if (\n currentUsernameInformation !== undefined &&\n currentUsernameInformation !== '' &&\n !isEmpty(data[currentUsernameInformation]) &&\n data[currentUsernameInformation]?.mainPresence !== undefined\n ) {\n let newMainPresenceValue = data[currentUsernameInformation]?.mainPresence\n store.dispatch.currentUser.updateMainPresence(data[currentUsernameInformation]?.mainPresence)\n let mainPresenceValueAfterUpdate = newMainPresenceValue\n if (mainPresenceValueAfterUpdate === 'online' && mainPresenceValueBeforeUpdate !== 'online') {\n eventDispatch('phone-island-call-ended', {})\n }\n }\n })\n\n useEventListener('phone-island-call-status', () => {\n const callInformation = store.getState().currentCall\n console.log('Call status debug informations: ', callInformation)\n })\n\n const openParameterizedUrl = (callerNum: any, callerName: any, called: any, uniqueId: any) => {\n const paramUrlInfo = store.getState().paramUrl\n\n if (!paramUrlInfo?.hasValidUrl) {\n return\n }\n\n const paramUrl = paramUrlInfo.url || ''\n\n if (!paramUrl) {\n return\n }\n\n const { urlOpened } = store.getState().island\n const openParamUrlType = paramUrlInfo.openParamUrlType\n\n if (urlOpened && openParamUrlType !== 'button') {\n return\n }\n\n let processedUrl = paramUrl\n\n if (processedUrl.includes('$CALLER_NUMBER') && callerNum) {\n processedUrl = processedUrl.replace(/\\$CALLER_NUMBER/g, encodeURIComponent(callerNum))\n }\n if (processedUrl.includes('$CALLER_NAME') && callerName) {\n processedUrl = processedUrl.replace(/\\$CALLER_NAME/g, encodeURIComponent(callerName))\n }\n if (processedUrl.includes('$UNIQUEID') && uniqueId) {\n processedUrl = processedUrl.replace(/\\$UNIQUEID/g, encodeURIComponent(uniqueId))\n }\n if (processedUrl.includes('$CALLED') && called) {\n processedUrl = processedUrl.replace(/\\$CALLED/g, encodeURIComponent(called))\n }\n if (processedUrl.includes('{phone}') && callerNum) {\n processedUrl = processedUrl.replace(/\\{phone\\}/g, encodeURIComponent(callerNum))\n }\n\n const formattedUrl = processedUrl.startsWith('http') ? processedUrl : `https://${processedUrl}`\n\n if (uaType !== 'mobile') {\n const newWindow = window.open('about:blank', '_blank')\n if (newWindow) {\n newWindow.location.href = formattedUrl\n store.dispatch.island.setUrlOpened(true)\n }\n } else {\n eventDispatch('phone-island-url-parameter-opened-external', { formattedUrl })\n }\n }\n\n useEventListener('phone-island-already-opened-external-page', () => {\n store.dispatch.island.setUrlOpened(true)\n })\n\n useEventListener('phone-island-url-parameter-opened', (data) => {\n const paramUrlInfo = store.getState().paramUrl\n\n if (!paramUrlInfo.hasValidUrl) {\n return\n }\n\n const { urlOpened } = store.getState().island\n if (urlOpened) {\n return\n }\n\n const onlyQueues = paramUrlInfo.onlyQueues || false\n const throughTrunk = isFromTrunk(data?.counterpartNum)\n store.dispatch.paramUrl.setThroughTrunk(throughTrunk)\n\n if (data?.direction === 'in') {\n if (onlyQueues === true && data?.throughQueue === true) {\n openParameterizedUrl(\n data?.counterpartNum,\n data?.counterpartName,\n data?.owner,\n data?.uniqueId,\n )\n } else if (onlyQueues === false && (throughTrunk === true || data?.throughQueue === true)) {\n openParameterizedUrl(\n data?.counterpartNum,\n data?.counterpartName,\n data?.owner,\n data?.uniqueId,\n )\n }\n }\n })\n\n useEventListener('phone-island-user-status', () => {\n const userInformation = store.getState().currentUser\n console.log('User status debug informations: ', userInformation)\n })\n\n useEventListener('phone-island-all-users-status', () => {\n const allUsersInformation = store.getState().users\n console.log('Users status debug informations: ', allUsersInformation)\n })\n\n useEventListener('phone-island-status', () => {\n const phoneIslandInformation = store.getState().island\n console.log('Phone island status debug informations: ', phoneIslandInformation)\n })\n\n useEventListener('phone-island-webrtc-status', () => {\n const webrtcInformation = store.getState().webrtc\n console.log('Webrtc status debug informations: ', webrtcInformation)\n })\n\n useEventListener('phone-island-player-status', () => {\n const playerInformation = store.getState().player\n console.log('Player status debug informations: ', playerInformation)\n })\n\n useEventListener('phone-island-conference-status', () => {\n const conferenceInformation = store.getState().conference\n console.log('Webrtc status debug informations: ', conferenceInformation)\n })\n\n useEventListener('phone-island-streaming-status', () => {\n const streamingInformation = store.getState().streaming\n console.log('Streaming status debug informations: ', streamingInformation)\n })\n\n useEventListener('phone-island-paramurl-status', () => {\n const paramurl = store.getState().paramUrl\n console.log('Paramurl status debug informations: ', paramurl)\n })\n\n useEventListener('phone-island-player-force-stop', () => {\n store.dispatch.player.reset()\n console.log('Audio player is interrupted')\n })\n\n useEventListener('phone-island-sideview-open', () => {\n store.dispatch.island.toggleSideViewVisible(true)\n store.dispatch.island.setUrlOpened(false)\n eventDispatch('phone-island-sideview-opened', {})\n })\n\n useEventListener('phone-island-sideview-close', () => {\n store.dispatch.island.toggleSideViewVisible(false)\n eventDispatch('phone-island-sideview-closed', {})\n })\n\n useEventListener('phone-island-size-change', (args: any) => {\n const { sideViewIsVisible } = store.getState().island\n\n // Get current dimensions from args\n const { sizeInformation } = args\n\n // // Calculate extra row dimension ( side view and back call )\n const updatedSizeInformation = {\n ...sizeInformation,\n right: sideViewIsVisible ? '42px' : '0px',\n top: isBackCallActive() ? '40px' : '0px',\n }\n eventDispatch('phone-island-size-changed', { sizes: updatedSizeInformation })\n })\n\n // Listen for the call end event and set the island size to 0\n useEventListener('phone-island-call-ended', () => {\n const { mainPresence } = store.getState().currentUser\n if (mainPresence === 'online') {\n const sizeInformation: any = {\n width: '0px',\n height: '0px',\n }\n eventDispatch('phone-island-size-change', { sizeInformation })\n eventDispatch('phone-island-sideview-close', {})\n store.dispatch.island.resetIslandStore()\n store.dispatch.paramUrl.setThroughTrunk(false)\n }\n })\n\n useEventListener('phone-island-conference-list-open', () => {\n store.dispatch.island.toggleConferenceList(true)\n eventDispatch('phone-island-conference-list-opened', {})\n })\n\n useEventListener('phone-island-alert-removed', (alertRemovedType) => {\n // Get current alerts status\n const { activeAlertsCount } = store.getState().alerts.status\n const { view, previousView } = store.getState().island\n const { isActive } = store.getState().conference\n const alertsData = store.getState().alerts.data\n const currentCall = store.getState().currentCall\n const { incoming, outgoing, accepted } = currentCall\n\n // Check if alert type was provided\n const alertType = alertRemovedType?.type\n\n // Check if user is in a call\n const isInCall =\n currentCall.incoming ||\n currentCall.outgoing ||\n currentCall.accepted ||\n currentCall.conversationId !== ''\n\n // Determine if the island should remain visible\n const shouldKeepVisible =\n incoming ||\n outgoing ||\n accepted ||\n activeAlertsCount > 0 ||\n view === 'player' ||\n view === 'recorder' ||\n view === 'physicalPhoneRecorder' ||\n (view === 'waitingConference' && isActive) ||\n (view === 'transfer' && isActive) ||\n (view === 'settings' && isActive) ||\n (view === 'settings' && (previousView === 'recorder' || previousView === 'player'))\n\n // Reset the island store only if:\n // 1. The island should not remain visible\n // 2. No more active alerts\n // 3. The specific alert is not active anymore\n // 4. User is not currently in a call\n if (\n !shouldKeepVisible &&\n activeAlertsCount === 0 &&\n (!alertType || (alertsData[alertType] && !alertsData[alertType].active)) &&\n !isInCall\n ) {\n const sizeInformation: any = {\n width: '0px',\n height: '0px',\n }\n eventDispatch('phone-island-size-change', { sizeInformation })\n eventDispatch('phone-island-sideview-close', {})\n store.dispatch.island.resetIslandStore()\n }\n })\n\n useEventListener('phone-island-conference-list-close', () => {\n store.dispatch.island.toggleConferenceList(false)\n eventDispatch('phone-island-conference-list-closed', {})\n })\n\n // Listen for conversations updates to handle 'answered' preference for parameterized URL\n useEventListener('phone-island-conversations', (data: any) => {\n // Get the current username (first key in the data object)\n const username = Object.keys(data)[0]\n const currentUsernameInformation: any = store.getState().currentUser?.username\n\n if (username === currentUsernameInformation) {\n const conversations = data[username].conversations\n const paramUrlInfo = store.getState().paramUrl\n const { urlOpened } = store.getState().island\n\n // Only proceed if URL is valid and not already opened\n if (!paramUrlInfo.hasValidUrl || urlOpened) {\n return\n }\n\n // Check if the openParamUrlType is set to 'answered'\n if (paramUrlInfo.openParamUrlType === 'answered') {\n // Check if there are any conversations\n if (conversations && Object.keys(conversations).length > 0) {\n // Get the first conversation (usually there's only one active call)\n const convId = Object.keys(conversations)[0]\n const conv = conversations[convId]\n\n // Check conditions: must be connected and incoming\n if (conv?.connected && conv?.direction === 'in') {\n const onlyQueues = paramUrlInfo.onlyQueues || false\n const calculatedThroughTrunk = isFromTrunk(conv.counterpartNum)\n // Update throughTrunk in paramUrl store\n store.dispatch.paramUrl.setThroughTrunk(calculatedThroughTrunk)\n\n // Check queue conditions based on preferences\n if (onlyQueues === true && conv?.throughQueue === true) {\n // Open URL only for queue calls when onlyQueues is true\n openParameterizedUrl(\n conv.counterpartNum,\n conv.counterpartName,\n conv.owner,\n conv.uniqueId,\n )\n } else if (\n onlyQueues === false &&\n (calculatedThroughTrunk === true || conv?.throughQueue === true)\n ) {\n // Open URL for both trunk and queue calls when onlyQueues is false\n openParameterizedUrl(\n conv.counterpartNum,\n conv.counterpartName,\n conv.owner,\n conv.uniqueId,\n )\n }\n }\n }\n }\n }\n })\n\n return (\n <>\n <Provider store={store}>\n <WebRTC\n hostName={HOST_NAME}\n sipExten={SIP_EXTEN}\n sipSecret={SIP_SECRET}\n sipHost={SIP_HOST}\n sipPort={SIP_PORT}\n reload={reload}\n reloadedCallback={() => setReloadedWebRTC(true)}\n uaType={uaType}\n >\n <RestAPI hostName={HOST_NAME} username={USERNAME} authToken={AUTH_TOKEN}>\n <Socket\n hostName={HOST_NAME}\n username={USERNAME}\n authToken={AUTH_TOKEN}\n reload={reload}\n reloadedCallback={() => setReloadedSocket(true)}\n uaType={uaType}\n >\n <Events sipHost={SIP_HOST}>\n <Island showAlways={showAlways} uaType={uaType} />\n </Events>\n </Socket>\n </RestAPI>\n </WebRTC>\n </Provider>\n </>\n )\n}\n\nPhoneIsland.displayName = 'PhoneIsland'\n"],"names":["PhoneIsland","_a","dataConfig","_b","showAlways","uaType","CONFIG","Base64","atob","split","HOST_NAME","USERNAME","AUTH_TOKEN","SIP_EXTEN","SIP_SECRET","SIP_HOST","SIP_PORT","_c","useState","reload","setReload","_d","reloadedWebRTC","setReloadedWebRTC","_e","reloadedSocket","setReloadedSocket","useEffect","worker","Worker","wakeUpWorker","type","onmessage","event","data","terminate","useEventListener","store","dispatch","island","toggleIsOpen","eventDispatch","setIslandView","detach","setJSONItem","deviceId","_f","firstRender","setFirstRender","_g","firstAudioOutputInit","setFirstAudioOutputInit","initI18n","__awaiter","getParamUrl","paramUrlResponse","sent","url","isValid","trim","paramUrl","setParamUrl","onlyQueues","only_queues","hasValidUrl","console","error","error_1","toggleAvoidToShow","number","setTimeout","remoteAudioElement","getState","player","remoteAudio","current","setSinkId","then","info","catch","err","changeOperatorStatus","viewType","defaultAudioOutputDevice","getJSONItem","checkDarkTheme","theme","setTheme","selectedTheme","currentUser","updateCurrentDefaultDevice","deviceInformationObject","alertType","alerts","setAlert","toString","checkInternetConnection","internetIsActive","intervalId","setInterval","clearInterval","currentUsernameInformation","username","currentUserObject","mainPresenceValueBeforeUpdate","mainPresence","undefined","isEmpty","newMainPresenceValue","updateMainPresence","callInformation","currentCall","log","openParameterizedUrl","callerNum","callerName","called","uniqueId","paramUrlInfo","urlOpened","openParamUrlType","processedUrl","includes","replace","encodeURIComponent","formattedUrl","startsWith","concat","newWindow","window","open","location","href","setUrlOpened","throughTrunk","isFromTrunk","counterpartNum","setThroughTrunk","direction","throughQueue","counterpartName","owner","userInformation","allUsersInformation","users","phoneIslandInformation","webrtcInformation","webrtc","playerInformation","conferenceInformation","conference","streamingInformation","streaming","paramurl","reset","toggleSideViewVisible","args","sideViewIsVisible","sizeInformation","updatedSizeInformation","__assign","right","top","isBackCallActive","sizes","width","height","resetIslandStore","toggleConferenceList","alertRemovedType","activeAlertsCount","status","view","previousView","isActive","alertsData","incoming","outgoing","accepted","isInCall","conversationId","active","Object","keys","conversations","length","conv","connected","calculatedThroughTrunk","React","createElement","Fragment","Provider","WebRTC","hostName","sipExten","sipSecret","sipHost","sipPort","reloadedCallback","RestAPI","authToken","Socket","Events","Island","displayName"],"mappings":"6kDA6BaA,EAAoC,SAACC,OAChDC,EAAUD,EAAAC,WACVC,EAAAF,EAAAG,WAAAA,cAAkBD,EAClBE,EAAMJ,EAAAI,OAEAC,EAAmBC,EAAMA,OAACC,KAAKN,GAAc,IAAIO,MAAM,KACvDC,EAAoBJ,EAAO,GAC3BK,EAAmBL,EAAO,GAC1BM,EAAqBN,EAAO,GAC5BO,EAAoBP,EAAO,GAC3BQ,EAAqBR,EAAO,GAC5BS,EAAmBT,EAAO,GAC1BU,EAAmBV,EAAO,GAG1BW,EAAsBC,EAAAA,UAAkB,GAAvCC,EAAMF,EAAA,GAAEG,EAASH,EAAA,GAClBI,EAAsCH,EAAAA,UAAkB,GAAvDI,EAAcD,EAAA,GAAEE,EAAiBF,EAAA,GAClCG,EAAsCN,EAAAA,UAAkB,GAAvDO,EAAcD,EAAA,GAAEE,EAAiBF,EAAA,GAExCG,EAAAA,WAAU,WACR,IAAMC,EAAS,IAAIC,OAAOC,EAAAA,QAAc,CAAEC,KAAM,WAQhD,OAPAH,EAAOI,UAAY,SAACC,GAEC,WAAfA,EAAMC,MACRd,GAAU,EAEd,EAEO,WACLQ,EAAOO,WACT,CACD,GAAE,IAEHR,EAAAA,WAAU,WACJF,GAAkBH,IACpBF,GAAU,GACVG,GAAkB,GAClBG,GAAkB,GAEtB,GAAG,CAACD,EAAgBH,IAEpBc,EAAgBA,iBAAC,uBAAuB,WACtCC,EAAAA,MAAMC,SAASC,OAAOC,cAAa,GACnCC,gBAAc,wBAAyB,CAAA,EACzC,IACAL,EAAgBA,iBAAC,yBAAyB,WACxCC,EAAAA,MAAMC,SAASC,OAAOC,cAAa,GACnCC,gBAAc,0BAA2B,CAAA,EAC3C,IAEAL,EAAgBA,iBAAC,kCAAkC,WACjDC,EAAAA,MAAMC,SAASC,OAAOG,cAAc,QACpCD,gBAAc,kCAAmC,CAAA,EACnD,IACAL,EAAgBA,iBAAC,oCAAoC,WACnDC,EAAAA,MAAMC,SAASC,OAAOG,cAAc,QACpCD,gBAAc,oCAAqC,CAAA,EACrD,IACAL,EAAgBA,iBAAC,gCAAgC,WAC/CC,EAAAA,MAAMC,SAASC,OAAOG,cAAc,MACpCD,gBAAc,gCAAiC,CAAA,EACjD,IACAL,EAAgBA,iBAAC,mCAAmC,WAClDC,EAAAA,MAAMC,SAASC,OAAOG,cAAc,MACpCD,gBAAc,mCAAoC,CAAA,EACpD,IAEAL,mBAAiB,uBAAuB,SAACF,GACvCS,EAAAA,SACAF,gBAAc,wBAAyB,CAAA,EACzC,IAEAL,mBAAiB,mCAAmC,SAACF,GACnDU,EAAWA,YAAC,kCAAmC,CAAEC,SAAUX,EAAKW,WAChEJ,gBAAc,mCAAoC,CAAA,EACpD,IAEAL,mBAAiB,mCAAmC,SAACF,GACnDU,EAAWA,YAAC,kCAAmC,CAAEC,SAAUX,EAAKW,WAChEJ,gBAAc,mCAAoC,CAAA,EACpD,IAEM,IAAAK,EAAgC5B,EAAAA,UAAS,GAAxC6B,EAAWD,EAAA,GAAEE,EAAcF,EAAA,GAC5BG,EAAkD/B,EAAAA,UAAS,GAA1DgC,EAAoBD,EAAA,GAAEE,EAAuBF,EAAA,GAGpDtB,EAAAA,WAAU,WAuBJoB,IAEFK,EAAAA,WAxBmBC,EAAAA,eAAA,OAAA,OAAA,GAAA,qFAEa,6BAAM,CAAA,EAAAC,EAAWA,6BAAzCC,EAAwBtD,EAAmBuD,OAC3CC,GAAMF,aAAA,EAAAA,EAAkBE,MAAO,GAC/BC,EAAUD,GAAsB,KAAfA,EAAIE,OAG3BtB,QAAMC,SAASsB,SAASC,YAAY,CAClCJ,IAAKA,EACLK,YAAYP,eAAAA,EAAkBQ,eAAe,EAC7CC,YAAaN,mCAGfO,QAAQC,MAAM,gCAAiCC,GAC/C9B,QAAMC,SAASsB,SAASC,YAAY,CAClCJ,IAAK,GACLK,YAAY,EACZE,aAAa,kCAUjBhB,GAAe,GAEnB,GAAG,CAACD,IAEJX,mBAAiB,oCAAoC,SAACF,GAC/CgB,IACHb,EAAAA,MAAMC,SAASC,OAAOG,cAAc,MACpCL,EAAAA,MAAMC,SAASC,OAAO6B,mBAAkB,GACxC3B,EAAAA,cAAc,0BAA2B,CAAE4B,OAAQ,SAGrDC,YAAW,WACT,IAAMC,EAA0BlC,EAAKA,MAACmC,WAAWC,OAAOC,YAExDH,SAAAA,EAAoBI,QACjBC,UAAU1C,EAAKW,UACfgC,MAAK,WACJZ,QAAQa,KAAK,oDAEblC,EAAWA,YAAC,mCAAoC,CAAEC,SAAUX,EAAKW,WAGjEJ,gBAAc,oCAAqC,CAAA,GACnDA,gBAAc,wBAAyB,CAAA,GACvCJ,EAAAA,MAAMC,SAASC,OAAO6B,mBAAkB,EAC1C,IACCW,OAAM,SAAUC,GACff,QAAQC,MAAM,4CAA6Cc,GAC3DvC,gBAAc,wBAAyB,CAAA,GACvCJ,EAAAA,MAAMC,SAASC,OAAO6B,mBAAkB,EAC1C,GACH,GAAE,IACL,IAGAhC,mBAAiB,gCAAgC,SAACF,GAChD+C,EAAoBA,qBAAC/C,GACrBO,gBAAc,gCAAiC,CAAA,EACjD,IAEAL,mBAAiB,6BAA6B,SAACF,GAC7C,IAAMgD,EAAWhD,aAAA,EAAAA,EAAMgD,SACvB7C,EAAAA,MAAMC,SAASC,OAAOG,cAAcwC,EACtC,IAEA,IAAMX,EAA0BlC,EAAKA,MAACmC,WAAWC,OAAOC,YAGxD/C,EAAAA,WAAU,iBACR,GAAIuB,GAAwBqB,EAAoB,CAC9C,IAAMY,EAEH,QAFmClF,EAAAmF,EAAWA,YAC/C,2CACC,IAAAnF,OAAA,EAAAA,EAAA4C,SACHJ,EAAAA,cAAc,mCAAoC,CAChDI,SAAUsC,IAEZhC,GAAwB,EACzB,CACH,GAAG,CAACD,EAAsBqB,IAE1B5C,EAAAA,WAAU,WACR0D,EAAAA,gBACD,GAAE,IAEHjD,mBAAiB,6BAA6B,SAACkD,GAC7CC,WAASD,eAAAA,EAAOE,cAClB,IAEApD,mBAAiB,sCAAsC,SAACF,GACtDG,EAAAA,MAAMC,SAASmD,YAAYC,2BAA2BxD,aAAA,EAAAA,EAAMyD,yBAC5DlD,gBAAc,sCAAuC,CAAA,EACvD,IAEAL,mBAAiB,sBAAsB,SAACwD,GACtCvD,EAAKA,MAACC,SAASuD,OAAOC,SAASF,EAAUG,WAC3C,IAGA3D,EAAgBA,iBAAC,iCAAiC,WAChD4D,4BAA0BnB,MAAK,SAACoB,GAC1BA,EACFxD,gBAAc,kCAAmC,CAAA,GAEjDA,gBAAc,qCAAsC,CAAA,EAExD,GACF,IAGAd,EAAAA,WAAU,WACR,IAAMuE,EAAaC,aAAY,WAC7BH,4BAA0BnB,MAAK,SAACoB,GAC1BA,EACFxD,gBAAc,kCAAmC,CAAA,GAEjDA,gBAAc,qCAAsC,CAAA,EAExD,GACD,GAAE,KAEH,OAAO,WAAM,OAAA2D,cAAcF,EAAW,CACvC,GAAE,IAEH9D,mBAAiB,8BAA8B,SAACF,eACxCmE,EAAgE,QAA9BpG,EAAAoC,EAAAA,MAAMmC,WAAWiB,mBAAa,IAAAxF,OAAA,EAAAA,EAAAqG,SAChEC,EAAyBlE,EAAAA,MAAMmC,WAAWiB,YAC5Ce,EAAgCD,aAAA,EAAAA,EAAmBE,aACvD,QACiCC,IAA/BL,GAC+B,KAA/BA,IACCM,EAAOA,QAACzE,EAAKmE,UACqCK,KAAjB,QAAlCvG,EAAA+B,EAAKmE,UAA6B,IAAAlG,OAAA,EAAAA,EAAAsG,cAClC,CACA,IAAIG,EAAyD,QAAlC3F,EAAAiB,EAAKmE,UAA6B,IAAApF,OAAA,EAAAA,EAAAwF,aAC7DpE,EAAKA,MAACC,SAASmD,YAAYoB,mBAAqD,QAAlCxF,EAAAa,EAAKmE,UAA6B,IAAAhF,OAAA,EAAAA,EAAAoF,cAE3C,WADFG,GACgD,WAAlCJ,GAC/C/D,gBAAc,0BAA2B,CAAA,EAE5C,CACH,IAEAL,EAAgBA,iBAAC,4BAA4B,WAC3C,IAAM0E,EAAkBzE,EAAAA,MAAMmC,WAAWuC,YACzC9C,QAAQ+C,IAAI,mCAAoCF,EAClD,IAEA,IAAMG,EAAuB,SAACC,EAAgBC,EAAiBC,EAAaC,GAC1E,IAAMC,EAAejF,EAAAA,MAAMmC,WAAWZ,SAEtC,GAAK0D,eAAAA,EAActD,YAAnB,CAIA,IAAMJ,EAAW0D,EAAa7D,KAAO,GAErC,GAAKG,EAAL,CAIQ,IAAA2D,EAAclF,EAAKA,MAACmC,WAAWjC,OAAMgF,UACvCC,EAAmBF,EAAaE,iBAEtC,IAAID,GAAkC,WAArBC,EAAjB,CAIA,IAAIC,EAAe7D,EAEf6D,EAAaC,SAAS,mBAAqBR,IAC7CO,EAAeA,EAAaE,QAAQ,mBAAoBC,mBAAmBV,KAEzEO,EAAaC,SAAS,iBAAmBP,IAC3CM,EAAeA,EAAaE,QAAQ,iBAAkBC,mBAAmBT,KAEvEM,EAAaC,SAAS,cAAgBL,IACxCI,EAAeA,EAAaE,QAAQ,cAAeC,mBAAmBP,KAEpEI,EAAaC,SAAS,YAAcN,IACtCK,EAAeA,EAAaE,QAAQ,YAAaC,mBAAmBR,KAElEK,EAAaC,SAAS,YAAcR,IACtCO,EAAeA,EAAaE,QAAQ,aAAcC,mBAAmBV,KAGvE,IAAMW,EAAeJ,EAAaK,WAAW,QAAUL,EAAe,WAAWM,OAAAN,GAEjF,GAAe,WAAXpH,EAAqB,CACvB,IAAM2H,EAAYC,OAAOC,KAAK,cAAe,UACzCF,IACFA,EAAUG,SAASC,KAAOP,EAC1BxF,EAAAA,MAAMC,SAASC,OAAO8F,cAAa,GAEtC,MACC5F,EAAAA,cAAc,6CAA8C,CAAEoF,aAAYA,GA7B3E,CAPA,CANA,CA4CH,EAyPA,OAvPAzF,EAAgBA,iBAAC,6CAA6C,WAC5DC,EAAAA,MAAMC,SAASC,OAAO8F,cAAa,EACrC,IAEAjG,mBAAiB,qCAAqC,SAACF,GACrD,IAAMoF,EAAejF,EAAAA,MAAMmC,WAAWZ,SAEtC,GAAK0D,EAAatD,cAII3B,EAAKA,MAACmC,WAAWjC,OAAMgF,UAC7C,CAIA,IAAMzD,EAAawD,EAAaxD,aAAc,EACxCwE,EAAeC,EAAAA,YAAYrG,aAAI,EAAJA,EAAMsG,gBACvCnG,EAAAA,MAAMC,SAASsB,SAAS6E,gBAAgBH,GAEhB,QAApBpG,aAAI,EAAJA,EAAMwG,cACW,IAAf5E,IAA8C,KAAvB5B,aAAI,EAAJA,EAAMyG,cAC/B1B,EACE/E,eAAAA,EAAMsG,eACNtG,aAAI,EAAJA,EAAM0G,gBACN1G,aAAA,EAAAA,EAAM2G,MACN3G,aAAA,EAAAA,EAAMmF,WAEgB,IAAfvD,IAA0C,IAAjBwE,IAAgD,KAAvBpG,eAAAA,EAAMyG,eACjE1B,EACE/E,eAAAA,EAAMsG,eACNtG,aAAI,EAAJA,EAAM0G,gBACN1G,aAAA,EAAAA,EAAM2G,MACN3G,aAAA,EAAAA,EAAMmF,UAnBX,CAuBH,IAEAjF,EAAgBA,iBAAC,4BAA4B,WAC3C,IAAM0G,EAAkBzG,EAAAA,MAAMmC,WAAWiB,YACzCxB,QAAQ+C,IAAI,mCAAoC8B,EAClD,IAEA1G,EAAgBA,iBAAC,iCAAiC,WAChD,IAAM2G,EAAsB1G,EAAAA,MAAMmC,WAAWwE,MAC7C/E,QAAQ+C,IAAI,oCAAqC+B,EACnD,IAEA3G,EAAgBA,iBAAC,uBAAuB,WACtC,IAAM6G,EAAyB5G,EAAAA,MAAMmC,WAAWjC,OAChD0B,QAAQ+C,IAAI,2CAA4CiC,EAC1D,IAEA7G,EAAgBA,iBAAC,8BAA8B,WAC7C,IAAM8G,EAAoB7G,EAAAA,MAAMmC,WAAW2E,OAC3ClF,QAAQ+C,IAAI,qCAAsCkC,EACpD,IAEA9G,EAAgBA,iBAAC,8BAA8B,WAC7C,IAAMgH,EAAoB/G,EAAAA,MAAMmC,WAAWC,OAC3CR,QAAQ+C,IAAI,qCAAsCoC,EACpD,IAEAhH,EAAgBA,iBAAC,kCAAkC,WACjD,IAAMiH,EAAwBhH,EAAAA,MAAMmC,WAAW8E,WAC/CrF,QAAQ+C,IAAI,qCAAsCqC,EACpD,IAEAjH,EAAgBA,iBAAC,iCAAiC,WAChD,IAAMmH,EAAuBlH,EAAAA,MAAMmC,WAAWgF,UAC9CvF,QAAQ+C,IAAI,wCAAyCuC,EACvD,IAEAnH,EAAgBA,iBAAC,gCAAgC,WAC/C,IAAMqH,EAAWpH,EAAAA,MAAMmC,WAAWZ,SAClCK,QAAQ+C,IAAI,uCAAwCyC,EACtD,IAEArH,EAAgBA,iBAAC,kCAAkC,WACjDC,EAAAA,MAAMC,SAASmC,OAAOiF,QACtBzF,QAAQ+C,IAAI,8BACd,IAEA5E,EAAgBA,iBAAC,8BAA8B,WAC7CC,EAAAA,MAAMC,SAASC,OAAOoH,uBAAsB,GAC5CtH,EAAAA,MAAMC,SAASC,OAAO8F,cAAa,GACnC5F,gBAAc,+BAAgC,CAAA,EAChD,IAEAL,EAAgBA,iBAAC,+BAA+B,WAC9CC,EAAAA,MAAMC,SAASC,OAAOoH,uBAAsB,GAC5ClH,gBAAc,+BAAgC,CAAA,EAChD,IAEAL,mBAAiB,4BAA4B,SAACwH,GACpC,IAAAC,EAAsBxH,EAAKA,MAACmC,WAAWjC,OAAMsH,kBAG7CC,EAAoBF,EAAIE,gBAG1BC,EAAsBC,EAAAA,SAAAA,EAAAA,SAAA,CAAA,EACvBF,GAAe,CAClBG,MAAOJ,EAAoB,OAAS,MACpCK,IAAKC,EAAAA,mBAAqB,OAAS,QAErC1H,EAAAA,cAAc,4BAA6B,CAAE2H,MAAOL,GACtD,IAGA3H,EAAgBA,iBAAC,2BAA2B,WAE1C,GAAqB,WADIC,EAAKA,MAACmC,WAAWiB,YAAWgB,aACtB,CAK7BhE,EAAAA,cAAc,2BAA4B,CAAEqH,gBAJf,CAC3BO,MAAO,MACPC,OAAQ,SAGV7H,gBAAc,8BAA+B,CAAA,GAC7CJ,EAAAA,MAAMC,SAASC,OAAOgI,mBACtBlI,EAAAA,MAAMC,SAASsB,SAAS6E,iBAAgB,EACzC,CACH,IAEArG,EAAgBA,iBAAC,qCAAqC,WACpDC,EAAAA,MAAMC,SAASC,OAAOiI,sBAAqB,GAC3C/H,gBAAc,sCAAuC,CAAA,EACvD,IAEAL,mBAAiB,8BAA8B,SAACqI,GAEtC,IAAAC,EAAsBrI,EAAAA,MAAMmC,WAAWqB,OAAO8E,OAAMD,kBACtDzK,EAAyBoC,EAAAA,MAAMmC,WAAWjC,OAAxCqI,EAAI3K,EAAA2K,KAAEC,iBACNC,EAAazI,EAAKA,MAACmC,WAAW8E,WAAUwB,SAC1CC,EAAa1I,EAAKA,MAACmC,WAAWqB,OAAO3D,KACrC6E,EAAc1E,EAAAA,MAAMmC,WAAWuC,YAC7BiE,EAAiCjE,EAAWiE,SAAlCC,EAAuBlE,EAAWkE,SAAxBC,EAAanE,WAGnCnB,EAAY6E,aAAA,EAAAA,EAAkB1I,KAG9BoJ,EACJpE,EAAYiE,UACZjE,EAAYkE,UACZlE,EAAYmE,UACmB,KAA/BnE,EAAYqE,eAqBd,KAjBEJ,GACAC,GACAC,GACAR,EAAoB,GACX,WAATE,GACS,aAATA,GACS,0BAATA,GACU,sBAATA,GAAgCE,GACvB,aAATF,GAAuBE,GACd,aAATF,GAAuBE,GACd,aAATF,IAAyC,aAAjBC,GAAgD,WAAjBA,KASlC,IAAtBH,KACE9E,GAAcmF,EAAWnF,KAAemF,EAAWnF,GAAWyF,UAC/DF,EACD,CAKA1I,EAAAA,cAAc,2BAA4B,CAAEqH,gBAJf,CAC3BO,MAAO,MACPC,OAAQ,SAGV7H,gBAAc,8BAA+B,CAAA,GAC7CJ,EAAAA,MAAMC,SAASC,OAAOgI,kBACvB,CACH,IAEAnI,EAAgBA,iBAAC,sCAAsC,WACrDC,EAAAA,MAAMC,SAASC,OAAOiI,sBAAqB,GAC3C/H,gBAAc,sCAAuC,CAAA,EACvD,IAGAL,mBAAiB,8BAA8B,SAACF,SAExCoE,EAAWgF,OAAOC,KAAKrJ,GAAM,GAGnC,GAAIoE,KAFkE,QAA9BrG,EAAAoC,EAAAA,MAAMmC,WAAWiB,mBAAa,IAAAxF,OAAA,EAAAA,EAAAqG,UAEzB,CAC3C,IAAMkF,EAAgBtJ,EAAKoE,GAAUkF,cAC/BlE,EAAejF,EAAAA,MAAMmC,WAAWZ,SAC9B2D,EAAclF,EAAKA,MAACmC,WAAWjC,OAAMgF,UAG7C,IAAKD,EAAatD,aAAeuD,EAC/B,OAIF,GAAsC,aAAlCD,EAAaE,kBAEXgE,GAAiBF,OAAOC,KAAKC,GAAeC,OAAS,EAAG,CAE1D,IACMC,EAAOF,EADEF,OAAOC,KAAKC,GAAe,IAI1C,IAAIE,aAAA,EAAAA,EAAMC,YAAiC,QAApBD,aAAA,EAAAA,EAAMhD,WAAoB,CAC/C,IAAM5E,EAAawD,EAAaxD,aAAc,EACxC8H,EAAyBrD,EAAAA,YAAYmD,EAAKlD,gBAEhDnG,EAAAA,MAAMC,SAASsB,SAAS6E,gBAAgBmD,IAGrB,IAAf9H,IAA8C,KAAvB4H,aAAI,EAAJA,EAAM/C,cAE/B1B,EACEyE,EAAKlD,eACLkD,EAAK9C,gBACL8C,EAAK7C,MACL6C,EAAKrE,WAGQ,IAAfvD,IAC4B,IAA3B8H,IAA0D,KAAvBF,aAAI,EAAJA,EAAM/C,eAG1C1B,EACEyE,EAAKlD,eACLkD,EAAK9C,gBACL8C,EAAK7C,MACL6C,EAAKrE,SAGV,CACF,CAEJ,CACH,IAGEwE,UAAAC,cAAAD,EAAA,QAAAE,SAAA,KACEF,EAAAA,QAAAC,cAACE,EAAAA,QAAQ,CAAC3J,MAAOA,EAAAA,OACfwJ,EAAAA,QAAAC,cAACG,SACC,CAAAC,SAAUxL,EACVyL,SAAUtL,EACVuL,UAAWtL,EACXuL,QAAStL,EACTuL,QAAStL,EACTG,OAAQA,EACRoL,iBAAkB,WAAM,OAAAhL,GAAkB,IAC1ClB,OAAQA,GAERwL,UAAAC,cAACU,EAAOA,QAAA,CAACN,SAAUxL,EAAW4F,SAAU3F,EAAU8L,UAAW7L,GAC3DiL,UAAAC,cAACY,EAAAA,OAAM,CACLR,SAAUxL,EACV4F,SAAU3F,EACV8L,UAAW7L,EACXO,OAAQA,EACRoL,iBAAkB,WAAM,OAAA7K,GAAkB,EAAlB,EACxBrB,OAAQA,GAERwL,EAAAA,QAAAC,cAACa,EAAAA,OAAM,CAACN,QAAStL,GACf8K,EAAAA,QAAAC,cAACc,SAAO,CAAAxM,WAAYA,EAAYC,OAAQA,SAQxD,EAEAL,EAAY6M,YAAc"}
|
|
1
|
+
{"version":3,"file":"App.js","sources":["../src/App.tsx"],"sourcesContent":["import React, { type FC, useState, useEffect } from 'react'\nimport { Events, Socket, WebRTC, Island, RestAPI } from './components'\nimport { Provider } from 'react-redux'\nimport { store } from './store'\nimport { Base64 } from 'js-base64'\nimport wakeUpWorker from './workers/wake_up'\nimport { initI18n } from './lib/i18n'\n\nimport 'react-tooltip/dist/react-tooltip.css'\nimport { useEventListener, eventDispatch, setJSONItem, getJSONItem } from './utils'\nimport { detach } from './lib/webrtc/messages'\nimport { checkDarkTheme, setTheme } from './lib/darkTheme'\nimport { changeOperatorStatus } from './services/user'\nimport { getParamUrl } from './services/user'\nimport { isEmpty } from './utils/genericFunctions/isEmpty'\nimport { checkInternetConnection } from './utils/genericFunctions/checkConnection'\nimport { isBackCallActive } from './utils/genericFunctions/isBackCallVisible'\nimport { isFromTrunk } from './lib/user/extensions'\n\ninterface PhoneIslandProps {\n dataConfig: string\n showAlways?: boolean\n uaType: string\n}\n\ninterface DeviceInputOutputTypes {\n deviceId: string\n}\n\nexport const PhoneIsland: FC<PhoneIslandProps> = ({\n dataConfig,\n showAlways = false,\n uaType,\n}: PhoneIslandProps) => {\n const CONFIG: string[] = Base64.atob(dataConfig || '').split(':')\n const HOST_NAME: string = CONFIG[0]\n const USERNAME: string = CONFIG[1]\n const AUTH_TOKEN: string = CONFIG[2]\n const SIP_EXTEN: string = CONFIG[3]\n const SIP_SECRET: string = CONFIG[4]\n const SIP_HOST: string = CONFIG[5]\n const SIP_PORT: string = CONFIG[6]\n\n // Initialize the state to manage the reload events\n const [reload, setReload] = useState<boolean>(false)\n const [reloadedWebRTC, setReloadedWebRTC] = useState<boolean>(false)\n const [reloadedSocket, setReloadedSocket] = useState<boolean>(false)\n\n useEffect(() => {\n const worker = new Worker(wakeUpWorker, { type: 'module' })\n worker.onmessage = (event: MessageEvent<string>) => {\n // Handle wakeup message\n if (event.data === 'wakeup') {\n setReload(true)\n }\n }\n\n return () => {\n worker.terminate()\n }\n }, [])\n\n useEffect(() => {\n if (reloadedSocket && reloadedWebRTC) {\n setReload(false)\n setReloadedWebRTC(false)\n setReloadedSocket(false)\n }\n }, [reloadedSocket, reloadedWebRTC])\n\n useEventListener('phone-island-expand', () => {\n store.dispatch.island.toggleIsOpen(true)\n eventDispatch('phone-island-expanded', {})\n })\n useEventListener('phone-island-compress', () => {\n store.dispatch.island.toggleIsOpen(false)\n eventDispatch('phone-island-compressed', {})\n })\n\n useEventListener('phone-island-call-keypad-close', () => {\n store.dispatch.island.setIslandView('call')\n eventDispatch('phone-island-call-keypad-closed', {})\n })\n useEventListener('phone-island-call-transfer-close', () => {\n store.dispatch.island.setIslandView('call')\n eventDispatch('phone-island-call-transfer-closed', {})\n })\n useEventListener('phone-island-recording-close', () => {\n store.dispatch.island.setIslandView(null)\n eventDispatch('phone-island-recording-closed', {})\n })\n useEventListener('phone-island-audio-player-close', () => {\n store.dispatch.island.setIslandView(null)\n eventDispatch('phone-island-audio-player-closed', {})\n })\n\n useEventListener('phone-island-detach', (data) => {\n detach()\n eventDispatch('phone-island-detached', {})\n })\n\n useEventListener('phone-island-audio-input-change', async (data: DeviceInputOutputTypes) => {\n let targetDeviceId = data.deviceId\n\n // Check if the requested device is available\n if (targetDeviceId && targetDeviceId !== 'default') {\n const isAvailable = await isAudioInputDeviceAvailable(targetDeviceId)\n\n if (!isAvailable) {\n console.warn(`Audio input device ${targetDeviceId} not available, falling back to default device`)\n targetDeviceId = await getDefaultAudioInputDevice()\n }\n }\n\n // Save the final device choice\n setJSONItem('phone-island-audio-input-device', { deviceId: targetDeviceId })\n eventDispatch('phone-island-audio-input-changed', {})\n\n if (targetDeviceId !== data.deviceId) {\n console.info(`Audio input device changed from ${data.deviceId} to ${targetDeviceId} (fallback)`)\n }\n })\n\n useEventListener('phone-island-video-input-change', async (data: DeviceInputOutputTypes) => {\n let targetDeviceId = data.deviceId\n\n // Check if the requested device is available\n if (targetDeviceId && targetDeviceId !== 'default') {\n const isAvailable = await isVideoInputDeviceAvailable(targetDeviceId)\n\n if (!isAvailable) {\n console.warn(`Video input device ${targetDeviceId} not available, falling back to default device`)\n targetDeviceId = await getDefaultVideoInputDevice()\n }\n }\n\n // Save the final device choice\n setJSONItem('phone-island-video-input-device', { deviceId: targetDeviceId })\n eventDispatch('phone-island-video-input-changed', {})\n\n if (targetDeviceId !== data.deviceId) {\n console.info(`Video input device changed from ${data.deviceId} to ${targetDeviceId} (fallback)`)\n }\n })\n\n const [firstRender, setFirstRender] = useState(true)\n const [firstAudioOutputInit, setFirstAudioOutputInit] = useState(true)\n\n // Initialize application on first render\n useEffect(() => {\n const initParamUrl = async () => {\n try {\n const paramUrlResponse: any = await getParamUrl()\n const url = paramUrlResponse?.url || ''\n const isValid = url && url.trim() !== ''\n\n // Save data inside the store\n store.dispatch.paramUrl.setParamUrl({\n url: url,\n onlyQueues: paramUrlResponse?.only_queues || false,\n hasValidUrl: isValid,\n })\n } catch (error) {\n console.error('Error fetching URL parameter:', error)\n store.dispatch.paramUrl.setParamUrl({\n url: '',\n onlyQueues: false,\n hasValidUrl: false,\n })\n }\n }\n\n if (firstRender) {\n // Initialize i18n\n initI18n()\n // Initialize param URL\n initParamUrl()\n setFirstRender(false)\n }\n }, [firstRender])\n\n // Helper function to check if an audio output device is available\n const isAudioOutputDeviceAvailable = async (deviceId: string): Promise<boolean> => {\n try {\n if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {\n return false\n }\n\n const devices = await navigator.mediaDevices.enumerateDevices()\n const audioOutputDevices = devices.filter(device => device.kind === 'audiooutput')\n\n return audioOutputDevices.some(device => device.deviceId === deviceId)\n } catch (err) {\n console.warn('Error checking device availability:', err)\n return false\n }\n }\n\n // Helper function to get default audio output device\n const getDefaultAudioOutputDevice = async (): Promise<string> => {\n try {\n if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {\n return 'default'\n }\n\n const devices = await navigator.mediaDevices.enumerateDevices()\n const audioOutputDevices = devices.filter(device => device.kind === 'audiooutput')\n\n // Find the default device (usually has deviceId 'default' or is the first one)\n const defaultDevice = audioOutputDevices.find(device =>\n device.deviceId === 'default' || device.deviceId === ''\n ) || audioOutputDevices[0]\n\n return defaultDevice ? defaultDevice.deviceId : 'default'\n } catch (err) {\n console.warn('Error getting default device:', err)\n return 'default'\n }\n }\n\n // Helper function to check if an audio input device is available\n const isAudioInputDeviceAvailable = async (deviceId: string): Promise<boolean> => {\n try {\n if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {\n return false\n }\n\n const devices = await navigator.mediaDevices.enumerateDevices()\n const audioInputDevices = devices.filter(device => device.kind === 'audioinput')\n\n return audioInputDevices.some(device => device.deviceId === deviceId)\n } catch (err) {\n console.warn('Error checking audio input device availability:', err)\n return false\n }\n }\n\n // Helper function to get default audio input device\n const getDefaultAudioInputDevice = async (): Promise<string> => {\n try {\n if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {\n return 'default'\n }\n\n const devices = await navigator.mediaDevices.enumerateDevices()\n const audioInputDevices = devices.filter(device => device.kind === 'audioinput')\n\n // Find the default device (usually has deviceId 'default' or is the first one)\n const defaultDevice = audioInputDevices.find(device =>\n device.deviceId === 'default' || device.deviceId === ''\n ) || audioInputDevices[0]\n\n return defaultDevice ? defaultDevice.deviceId : 'default'\n } catch (err) {\n console.warn('Error getting default audio input device:', err)\n return 'default'\n }\n }\n\n // Helper function to check if a video input device is available\n const isVideoInputDeviceAvailable = async (deviceId: string): Promise<boolean> => {\n try {\n if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {\n return false\n }\n\n const devices = await navigator.mediaDevices.enumerateDevices()\n const videoInputDevices = devices.filter(device => device.kind === 'videoinput')\n\n return videoInputDevices.some(device => device.deviceId === deviceId)\n } catch (err) {\n console.warn('Error checking video input device availability:', err)\n return false\n }\n }\n\n // Helper function to get default video input device\n const getDefaultVideoInputDevice = async (): Promise<string> => {\n try {\n if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {\n return 'default'\n }\n\n const devices = await navigator.mediaDevices.enumerateDevices()\n const videoInputDevices = devices.filter(device => device.kind === 'videoinput')\n\n // Find the default device (usually has deviceId 'default' or is the first one)\n const defaultDevice = videoInputDevices.find(device =>\n device.deviceId === 'default' || device.deviceId === ''\n ) || videoInputDevices[0]\n\n return defaultDevice ? defaultDevice.deviceId : 'default'\n } catch (err) {\n console.warn('Error getting default video input device:', err)\n return 'default'\n }\n }\n\n useEventListener('phone-island-audio-output-change', (data: DeviceInputOutputTypes) => {\n const trySetSinkId = async () => {\n const remoteAudioElement: any = store.getState().player.remoteAudio\n\n if (!remoteAudioElement?.current) {\n console.warn('Remote audio element not available')\n return\n }\n\n let targetDeviceId = data.deviceId\n\n // Check if the requested device is available\n if (targetDeviceId && targetDeviceId !== 'default') {\n const isAvailable = await isAudioOutputDeviceAvailable(targetDeviceId)\n\n if (!isAvailable) {\n console.warn(`Audio output device ${targetDeviceId} not available, falling back to default device`)\n targetDeviceId = await getDefaultAudioOutputDevice()\n\n // Update localStorage with the fallback device\n setJSONItem('phone-island-audio-output-device', { deviceId: targetDeviceId })\n }\n }\n\n try {\n // Try to set sink ID directly first (works if audio element is already active)\n await remoteAudioElement.current.setSinkId(targetDeviceId)\n console.info('Default audio output device changed successfully!')\n\n // Save device to localStorage\n setJSONItem('phone-island-audio-output-device', { deviceId: targetDeviceId })\n eventDispatch('phone-island-audio-output-changed', {})\n\n } catch (err) {\n console.log('Direct setSinkId failed, trying with temporary stream:', err)\n\n try {\n // Create a temporary silent audio stream to activate the audio element\n const audioContext = new (window.AudioContext || (window as any).webkitAudioContext)()\n const oscillator = audioContext.createOscillator()\n const gainNode = audioContext.createGain()\n\n // Create silent audio\n oscillator.frequency.setValueAtTime(440, audioContext.currentTime)\n gainNode.gain.setValueAtTime(0, audioContext.currentTime) // Silent\n\n oscillator.connect(gainNode)\n\n // Get MediaStream from audio context\n const destination = audioContext.createMediaStreamDestination()\n gainNode.connect(destination)\n\n // Set the stream to the audio element\n remoteAudioElement.current.srcObject = destination.stream\n\n // Start the oscillator\n oscillator.start()\n\n // Try setSinkId again after a short delay\n setTimeout(async () => {\n try {\n await remoteAudioElement.current.setSinkId(targetDeviceId)\n console.info('Default audio output device changed successfully with temporary stream!')\n\n // Clean up temporary stream\n oscillator.stop()\n audioContext.close()\n remoteAudioElement.current.srcObject = null\n\n // Save device to localStorage\n setJSONItem('phone-island-audio-output-device', { deviceId: targetDeviceId })\n eventDispatch('phone-island-audio-output-changed', {})\n\n } catch (finalErr) {\n console.error('Final setSinkId attempt failed:', finalErr)\n\n // Clean up on failure\n oscillator.stop()\n audioContext.close()\n remoteAudioElement.current.srcObject = null\n\n // If original device failed and we're not already using default, try default\n if (targetDeviceId !== 'default') {\n console.log('Trying fallback to default device')\n try {\n await remoteAudioElement.current.setSinkId('default')\n setJSONItem('phone-island-audio-output-device', { deviceId: 'default' })\n console.info('Fallback to default audio device successful')\n } catch (defaultErr) {\n console.error('Even default device failed:', defaultErr)\n }\n }\n\n // Save device preference anyway for future calls\n setJSONItem('phone-island-audio-output-device', { deviceId: targetDeviceId })\n eventDispatch('phone-island-audio-output-changed', {})\n }\n }, 100)\n\n } catch (streamErr) {\n console.error('Failed to create temporary audio stream:', streamErr)\n\n // Final fallback: try default device\n if (targetDeviceId !== 'default') {\n try {\n await remoteAudioElement.current.setSinkId('default')\n setJSONItem('phone-island-audio-output-device', { deviceId: 'default' })\n console.info('Emergency fallback to default audio device successful')\n } catch (defaultErr) {\n console.error('Emergency fallback to default device failed:', defaultErr)\n setJSONItem('phone-island-audio-output-device', { deviceId: targetDeviceId })\n }\n } else {\n setJSONItem('phone-island-audio-output-device', { deviceId: targetDeviceId })\n }\n\n eventDispatch('phone-island-audio-output-changed', {})\n }\n }\n }\n\n trySetSinkId()\n })\n\n // Listen for the operator status change\n useEventListener('phone-island-presence-change', (data: any) => {\n changeOperatorStatus(data)\n eventDispatch('phone-island-presence-changed', {})\n })\n\n useEventListener('phone-island-view-changed', (data) => {\n const viewType = data?.viewType\n store.dispatch.island.setIslandView(viewType)\n })\n\n const remoteAudioElement: any = store.getState().player.remoteAudio\n\n //get output device from localstorage\n useEffect(() => {\n if (firstAudioOutputInit && remoteAudioElement) {\n const defaultAudioOutputDevice: any = getJSONItem(\n `phone-island-audio-output-device`,\n )?.deviceId\n eventDispatch('phone-island-audio-output-change', {\n deviceId: defaultAudioOutputDevice,\n })\n setFirstAudioOutputInit(false)\n }\n }, [firstAudioOutputInit, remoteAudioElement])\n\n useEffect(() => {\n checkDarkTheme()\n }, [])\n\n useEventListener('phone-island-theme-change', (theme: any) => {\n setTheme(theme?.selectedTheme)\n })\n\n useEventListener('phone-island-default-device-change', (data) => {\n store.dispatch.currentUser.updateCurrentDefaultDevice(data?.deviceInformationObject)\n eventDispatch('phone-island-default-device-changed', {})\n })\n\n useEventListener('phone-island-alert', (alertType: any) => {\n store.dispatch.alerts.setAlert(alertType.toString())\n })\n\n // Manually check if internet connection is enabled or not\n useEventListener('phone-island-check-connection', () => {\n checkInternetConnection().then((internetIsActive) => {\n if (internetIsActive) {\n eventDispatch('phone-island-internet-connected', {})\n } else {\n eventDispatch('phone-island-internet-disconnected', {})\n }\n })\n })\n\n // Check internet connection every 5 seconds\n useEffect(() => {\n const intervalId = setInterval(() => {\n checkInternetConnection().then((internetIsActive) => {\n if (internetIsActive) {\n eventDispatch('phone-island-internet-connected', {})\n } else {\n eventDispatch('phone-island-internet-disconnected', {})\n }\n })\n }, 5000)\n\n return () => clearInterval(intervalId)\n }, [])\n\n useEventListener('phone-island-main-presence', (data: any) => {\n const currentUsernameInformation: any = store.getState().currentUser?.username\n const currentUserObject: any = store.getState().currentUser\n let mainPresenceValueBeforeUpdate = currentUserObject?.mainPresence\n if (\n currentUsernameInformation !== undefined &&\n currentUsernameInformation !== '' &&\n !isEmpty(data[currentUsernameInformation]) &&\n data[currentUsernameInformation]?.mainPresence !== undefined\n ) {\n let newMainPresenceValue = data[currentUsernameInformation]?.mainPresence\n store.dispatch.currentUser.updateMainPresence(data[currentUsernameInformation]?.mainPresence)\n let mainPresenceValueAfterUpdate = newMainPresenceValue\n if (mainPresenceValueAfterUpdate === 'online' && mainPresenceValueBeforeUpdate !== 'online') {\n eventDispatch('phone-island-call-ended', {})\n }\n }\n })\n\n useEventListener('phone-island-call-status', () => {\n const callInformation = store.getState().currentCall\n console.log('Call status debug informations: ', callInformation)\n })\n\n const openParameterizedUrl = (callerNum: any, callerName: any, called: any, uniqueId: any) => {\n const paramUrlInfo = store.getState().paramUrl\n\n if (!paramUrlInfo?.hasValidUrl) {\n return\n }\n\n const paramUrl = paramUrlInfo.url || ''\n\n if (!paramUrl) {\n return\n }\n\n const { urlOpened } = store.getState().island\n const openParamUrlType = paramUrlInfo.openParamUrlType\n\n if (urlOpened && openParamUrlType !== 'button') {\n return\n }\n\n let processedUrl = paramUrl\n\n if (processedUrl.includes('$CALLER_NUMBER') && callerNum) {\n processedUrl = processedUrl.replace(/\\$CALLER_NUMBER/g, encodeURIComponent(callerNum))\n }\n if (processedUrl.includes('$CALLER_NAME') && callerName) {\n processedUrl = processedUrl.replace(/\\$CALLER_NAME/g, encodeURIComponent(callerName))\n }\n if (processedUrl.includes('$UNIQUEID') && uniqueId) {\n processedUrl = processedUrl.replace(/\\$UNIQUEID/g, encodeURIComponent(uniqueId))\n }\n if (processedUrl.includes('$CALLED') && called) {\n processedUrl = processedUrl.replace(/\\$CALLED/g, encodeURIComponent(called))\n }\n if (processedUrl.includes('{phone}') && callerNum) {\n processedUrl = processedUrl.replace(/\\{phone\\}/g, encodeURIComponent(callerNum))\n }\n\n const formattedUrl = processedUrl.startsWith('http') ? processedUrl : `https://${processedUrl}`\n\n if (uaType !== 'mobile') {\n const newWindow = window.open('about:blank', '_blank')\n if (newWindow) {\n newWindow.location.href = formattedUrl\n store.dispatch.island.setUrlOpened(true)\n }\n } else {\n eventDispatch('phone-island-url-parameter-opened-external', { formattedUrl })\n }\n }\n\n useEventListener('phone-island-already-opened-external-page', () => {\n store.dispatch.island.setUrlOpened(true)\n })\n\n useEventListener('phone-island-url-parameter-opened', (data) => {\n const paramUrlInfo = store.getState().paramUrl\n\n if (!paramUrlInfo.hasValidUrl) {\n return\n }\n\n const { urlOpened } = store.getState().island\n if (urlOpened) {\n return\n }\n\n const onlyQueues = paramUrlInfo.onlyQueues || false\n const throughTrunk = isFromTrunk(data?.counterpartNum)\n store.dispatch.paramUrl.setThroughTrunk(throughTrunk)\n\n if (data?.direction === 'in') {\n if (onlyQueues === true && data?.throughQueue === true) {\n openParameterizedUrl(\n data?.counterpartNum,\n data?.counterpartName,\n data?.owner,\n data?.uniqueId,\n )\n } else if (onlyQueues === false && (throughTrunk === true || data?.throughQueue === true)) {\n openParameterizedUrl(\n data?.counterpartNum,\n data?.counterpartName,\n data?.owner,\n data?.uniqueId,\n )\n }\n }\n })\n\n useEventListener('phone-island-user-status', () => {\n const userInformation = store.getState().currentUser\n console.log('User status debug informations: ', userInformation)\n })\n\n useEventListener('phone-island-all-users-status', () => {\n const allUsersInformation = store.getState().users\n console.log('Users status debug informations: ', allUsersInformation)\n })\n\n useEventListener('phone-island-status', () => {\n const phoneIslandInformation = store.getState().island\n console.log('Phone island status debug informations: ', phoneIslandInformation)\n })\n\n useEventListener('phone-island-webrtc-status', () => {\n const webrtcInformation = store.getState().webrtc\n console.log('Webrtc status debug informations: ', webrtcInformation)\n })\n\n useEventListener('phone-island-player-status', () => {\n const playerInformation = store.getState().player\n console.log('Player status debug informations: ', playerInformation)\n })\n\n useEventListener('phone-island-conference-status', () => {\n const conferenceInformation = store.getState().conference\n console.log('Webrtc status debug informations: ', conferenceInformation)\n })\n\n useEventListener('phone-island-streaming-status', () => {\n const streamingInformation = store.getState().streaming\n console.log('Streaming status debug informations: ', streamingInformation)\n })\n\n useEventListener('phone-island-paramurl-status', () => {\n const paramurl = store.getState().paramUrl\n console.log('Paramurl status debug informations: ', paramurl)\n })\n\n useEventListener('phone-island-player-force-stop', () => {\n store.dispatch.player.reset()\n console.log('Audio player is interrupted')\n })\n\n useEventListener('phone-island-sideview-open', () => {\n store.dispatch.island.toggleSideViewVisible(true)\n store.dispatch.island.setUrlOpened(false)\n eventDispatch('phone-island-sideview-opened', {})\n })\n\n useEventListener('phone-island-sideview-close', () => {\n store.dispatch.island.toggleSideViewVisible(false)\n eventDispatch('phone-island-sideview-closed', {})\n })\n\n useEventListener('phone-island-size-change', (args: any) => {\n const { sideViewIsVisible } = store.getState().island\n\n // Get current dimensions from args\n const { sizeInformation } = args\n\n // // Calculate extra row dimension ( side view and back call )\n const updatedSizeInformation = {\n ...sizeInformation,\n right: sideViewIsVisible ? '42px' : '0px',\n top: isBackCallActive() ? '40px' : '0px',\n }\n eventDispatch('phone-island-size-changed', { sizes: updatedSizeInformation })\n })\n\n // Listen for the call end event and set the island size to 0\n useEventListener('phone-island-call-ended', () => {\n const { mainPresence } = store.getState().currentUser\n if (mainPresence === 'online') {\n const sizeInformation: any = {\n width: '0px',\n height: '0px',\n }\n eventDispatch('phone-island-size-change', { sizeInformation })\n eventDispatch('phone-island-sideview-close', {})\n store.dispatch.island.resetIslandStore()\n store.dispatch.paramUrl.setThroughTrunk(false)\n }\n })\n\n useEventListener('phone-island-conference-list-open', () => {\n store.dispatch.island.toggleConferenceList(true)\n eventDispatch('phone-island-conference-list-opened', {})\n })\n\n useEventListener('phone-island-alert-removed', (alertRemovedType) => {\n // Get current alerts status\n const { activeAlertsCount } = store.getState().alerts.status\n const { view, previousView } = store.getState().island\n const { isActive } = store.getState().conference\n const alertsData = store.getState().alerts.data\n const currentCall = store.getState().currentCall\n const { incoming, outgoing, accepted } = currentCall\n\n // Check if alert type was provided\n const alertType = alertRemovedType?.type\n\n // Check if user is in a call\n const isInCall =\n currentCall.incoming ||\n currentCall.outgoing ||\n currentCall.accepted ||\n currentCall.conversationId !== ''\n\n // Determine if the island should remain visible\n const shouldKeepVisible =\n incoming ||\n outgoing ||\n accepted ||\n activeAlertsCount > 0 ||\n view === 'player' ||\n view === 'recorder' ||\n view === 'physicalPhoneRecorder' ||\n (view === 'waitingConference' && isActive) ||\n (view === 'transfer' && isActive) ||\n (view === 'settings' && isActive) ||\n (view === 'settings' && (previousView === 'recorder' || previousView === 'player'))\n\n // Reset the island store only if:\n // 1. The island should not remain visible\n // 2. No more active alerts\n // 3. The specific alert is not active anymore\n // 4. User is not currently in a call\n if (\n !shouldKeepVisible &&\n activeAlertsCount === 0 &&\n (!alertType || (alertsData[alertType] && !alertsData[alertType].active)) &&\n !isInCall\n ) {\n const sizeInformation: any = {\n width: '0px',\n height: '0px',\n }\n eventDispatch('phone-island-size-change', { sizeInformation })\n eventDispatch('phone-island-sideview-close', {})\n store.dispatch.island.resetIslandStore()\n }\n })\n\n useEventListener('phone-island-conference-list-close', () => {\n store.dispatch.island.toggleConferenceList(false)\n eventDispatch('phone-island-conference-list-closed', {})\n })\n\n // Listen for conversations updates to handle 'answered' preference for parameterized URL\n useEventListener('phone-island-conversations', (data: any) => {\n // Get the current username (first key in the data object)\n const username = Object.keys(data)[0]\n const currentUsernameInformation: any = store.getState().currentUser?.username\n\n if (username === currentUsernameInformation) {\n const conversations = data[username].conversations\n const paramUrlInfo = store.getState().paramUrl\n const { urlOpened } = store.getState().island\n\n // Only proceed if URL is valid and not already opened\n if (!paramUrlInfo.hasValidUrl || urlOpened) {\n return\n }\n\n // Check if the openParamUrlType is set to 'answered'\n if (paramUrlInfo.openParamUrlType === 'answered') {\n // Check if there are any conversations\n if (conversations && Object.keys(conversations).length > 0) {\n // Get the first conversation (usually there's only one active call)\n const convId = Object.keys(conversations)[0]\n const conv = conversations[convId]\n\n // Check conditions: must be connected and incoming\n if (conv?.connected && conv?.direction === 'in') {\n const onlyQueues = paramUrlInfo.onlyQueues || false\n const calculatedThroughTrunk = isFromTrunk(conv.counterpartNum)\n // Update throughTrunk in paramUrl store\n store.dispatch.paramUrl.setThroughTrunk(calculatedThroughTrunk)\n\n // Check queue conditions based on preferences\n if (onlyQueues === true && conv?.throughQueue === true) {\n // Open URL only for queue calls when onlyQueues is true\n openParameterizedUrl(\n conv.counterpartNum,\n conv.counterpartName,\n conv.owner,\n conv.uniqueId,\n )\n } else if (\n onlyQueues === false &&\n (calculatedThroughTrunk === true || conv?.throughQueue === true)\n ) {\n // Open URL for both trunk and queue calls when onlyQueues is false\n openParameterizedUrl(\n conv.counterpartNum,\n conv.counterpartName,\n conv.owner,\n conv.uniqueId,\n )\n }\n }\n }\n }\n }\n })\n\n return (\n <>\n <Provider store={store}>\n <WebRTC\n hostName={HOST_NAME}\n sipExten={SIP_EXTEN}\n sipSecret={SIP_SECRET}\n sipHost={SIP_HOST}\n sipPort={SIP_PORT}\n reload={reload}\n reloadedCallback={() => setReloadedWebRTC(true)}\n uaType={uaType}\n >\n <RestAPI hostName={HOST_NAME} username={USERNAME} authToken={AUTH_TOKEN}>\n <Socket\n hostName={HOST_NAME}\n username={USERNAME}\n authToken={AUTH_TOKEN}\n reload={reload}\n reloadedCallback={() => setReloadedSocket(true)}\n uaType={uaType}\n >\n <Events sipHost={SIP_HOST}>\n <Island showAlways={showAlways} uaType={uaType} />\n </Events>\n </Socket>\n </RestAPI>\n </WebRTC>\n </Provider>\n </>\n )\n}\n\nPhoneIsland.displayName = 'PhoneIsland'\n"],"names":["PhoneIsland","_a","dataConfig","_b","showAlways","uaType","CONFIG","Base64","atob","split","HOST_NAME","USERNAME","AUTH_TOKEN","SIP_EXTEN","SIP_SECRET","SIP_HOST","SIP_PORT","_c","useState","reload","setReload","_d","reloadedWebRTC","setReloadedWebRTC","_e","reloadedSocket","setReloadedSocket","useEffect","worker","Worker","wakeUpWorker","type","onmessage","event","data","terminate","useEventListener","store","dispatch","island","toggleIsOpen","eventDispatch","setIslandView","detach","__awaiter","targetDeviceId","deviceId","isAudioInputDeviceAvailable","sent","console","warn","getDefaultAudioInputDevice","setJSONItem","info","concat","isVideoInputDeviceAvailable","getDefaultVideoInputDevice","_f","firstRender","setFirstRender","_g","firstAudioOutputInit","setFirstAudioOutputInit","initI18n","getParamUrl","paramUrlResponse","url","isValid","trim","paramUrl","setParamUrl","onlyQueues","only_queues","hasValidUrl","error","error_1","navigator","mediaDevices","enumerateDevices","devices","filter","device","kind","some","err_3","audioInputDevices","defaultDevice","find","err_4","err_5","videoInputDevices","err_6","remoteAudioElement","getState","player","remoteAudio","current","err_1","audioOutputDevices","err_2","setSinkId","log","err_7","audioContext_1","window","AudioContext","webkitAudioContext","oscillator_1","createOscillator","gainNode","createGain","frequency","setValueAtTime","currentTime","gain","connect","destination","createMediaStreamDestination","srcObject","stream","start","setTimeout","stop","close","finalErr_1","defaultErr_2","streamErr_1","defaultErr_1","changeOperatorStatus","viewType","defaultAudioOutputDevice","getJSONItem","checkDarkTheme","theme","setTheme","selectedTheme","currentUser","updateCurrentDefaultDevice","deviceInformationObject","alertType","alerts","setAlert","toString","checkInternetConnection","then","internetIsActive","intervalId","setInterval","clearInterval","currentUsernameInformation","username","currentUserObject","mainPresenceValueBeforeUpdate","mainPresence","undefined","isEmpty","newMainPresenceValue","updateMainPresence","callInformation","currentCall","openParameterizedUrl","callerNum","callerName","called","uniqueId","paramUrlInfo","urlOpened","openParamUrlType","processedUrl","includes","replace","encodeURIComponent","formattedUrl","startsWith","newWindow","open","location","href","setUrlOpened","throughTrunk","isFromTrunk","counterpartNum","setThroughTrunk","direction","throughQueue","counterpartName","owner","userInformation","allUsersInformation","users","phoneIslandInformation","webrtcInformation","webrtc","playerInformation","conferenceInformation","conference","streamingInformation","streaming","paramurl","reset","toggleSideViewVisible","args","sideViewIsVisible","sizeInformation","updatedSizeInformation","__assign","right","top","isBackCallActive","sizes","width","height","resetIslandStore","toggleConferenceList","alertRemovedType","activeAlertsCount","status","view","previousView","isActive","alertsData","incoming","outgoing","accepted","isInCall","conversationId","active","Object","keys","conversations","length","conv","connected","calculatedThroughTrunk","React","createElement","Fragment","Provider","WebRTC","hostName","sipExten","sipSecret","sipHost","sipPort","reloadedCallback","RestAPI","authToken","Socket","Events","Island","displayName"],"mappings":"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"}
|
|
@@ -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("../lib/phone/conversation.js"),o=require("../services/user.js"),i=require("../utils/genericFunctions/eventDispatch.js"),s=require("../utils/genericFunctions/withTimeout.js"),c=require("../store/index.js");require("../lib/webrtc/janus.js"),require("../node_modules/webrtc-adapter/src/js/adapter_core.js");var a=require("../lib/devices/devices.js"),u=require("../lib/user/default_device.js"),l=require("../utils/genericFunctions/isEmpty.js"),d=require("../utils/streaming/getStreamingSourceId.js"),p=require("../events/SocketEvents.js"),m=require("../utils/genericFunctions/timestamp.js"),v=require("../lib/user/extensions.js"),g=require("../utils/streaming/isFromStreaming.js"),h=require("../node_modules/react-redux/es/hooks/useSelector.js");require("../node_modules/react-redux/es/components/Context.js"),require("../node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js"),require("../node_modules/react-redux/node_modules/react-is/index.js");var f=require("../node_modules/react-redux/es/hooks/useDispatch.js"),S=require("../lib/phone/trunk.js");function b(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var y=b(n);exports.Socket=function(b){var k=b.hostName,w=b.username,C=b.authToken,_=b.reload,N=b.reloadedCallback,D=b.children,j=b.uaType,U=f.useDispatch(),T=n.useRef(),x=n.useRef(),q=n.useRef(!1);h.useSelector((function(e){return e.currentUser}));return n.useEffect((function(){var n=function(e){if(e.counterpartNum&&g.isFromStreaming(e.counterpartNum)){U.island.setIsFromStreaming(!0),U.currentCall.updateCurrentCall({streamingSourceNumber:e.counterpartNum});var n=d.getStreamingSourceId(e.counterpartNum);n&&o.subscribe({id:n}).catch((function(e){return console.error("Error subscribing to streaming source:",e)}))}},h=function(t,s){var a=c.store.getState().currentCall,l=a.transferring,d=a.transferSwitching,p=a.transferCalls,g=c.store.getState().island.view;if(Object.keys(s).length>0){if(t.status){var h=c.store.getState().users.extensions,f=c.store.getState().currentUser.default_device,b=c.store.getState().currentUser,y=b.endpoints,k=b.username,w=c.store.getState().currentCall;w.incoming,w.outgoing;var C=function(){if(!h||!k)return!1;var e=Object.values(h).filter((function(e){return(null==e?void 0:e.username)===k}));return null==e?void 0:e.some((function(e){var n=null==y?void 0:y.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(t.status){case"ringing":if(n(s),"mobile"===j&&C()||"desktop"===j&&("webrtc"===(null==f?void 0:f.type)||void 0===(null==f?void 0:f.type)&&!C()||!C()&&"physical"===(null==f?void 0:f.type))){q.current||(q.current=!0,o.getCurrentUserInfo().then((function(n){n&&(U.currentUser.updateCurrentUser(n),i.eventDispatch("phone-island-user-informations-update",e.__assign({},n)),n.settings&&n.settings.open_param_url?U.paramUrl.setOpenParamUrlType(n.settings.open_param_url):U.paramUrl.setOpenParamUrlType("never"))})).catch((function(e){console.error("Error getting current user info:",e)})).finally((function(){setTimeout((function(){q.current=!1}),100)}))),U.currentCall.checkIncomingUpdatePlay({conversationId:s.id,displayName:r.getDisplayName(s),number:"".concat(s.counterpartNum),incomingSocket:!0,incoming:!0,username:"".concat(h&&h[s.counterpartNum]&&h[s.counterpartNum].username)||"",ownerExtension:s.owner}),s.id,r.getDisplayName(s),"".concat(s.counterpartNum),s.owner,"".concat(h&&h[s.counterpartNum]&&h[s.counterpartNum].username),null==s||s.chDest,null==s||s.chSource,s.direction,s.inConference,s.linkedId,s.uniqueId,s.throughQueue,s.throughTrunk,s.recording,c.store.dispatch.island.setIslandView("call"),i.eventDispatch("phone-island-call-ringing",{});var _=c.store.getState().paramUrl.openParamUrlType,N=c.store.getState().island.urlOpened;if("ringing"===_&&!N){var D=S.isFromTrunk(s.counterpartNum);c.store.dispatch.paramUrl.setThroughTrunk(D),c.store.dispatch.island.setUrlOpened(!1),i.eventDispatch("phone-island-url-parameter-opened",{counterpartNum:s.counterpartNum,counterpartName:r.getDisplayName(s),owner:s.owner,uniqueId:s.uniqueId,throughQueue:s.throughQueue,throughTrunk:D,direction:s.direction,connected:s.connected})}}break;case"busy":if(n(s),"mobile"===j&&C()||"desktop"===j&&("webrtc"===(null==f?void 0:f.type)||void 0===(null==f?void 0:f.type)&&!C()||!C()&&"physical"===(null==f?void 0:f.type))){if(s&&s.connected)U.currentCall.updateCurrentCall({conversationId:s.id,displayName:r.getDisplayName(s),number:"".concat(s.counterpartNum),ownerExtension:s.owner,username:"".concat(h&&h[s.counterpartNum]&&h[s.counterpartNum].username)||"",chDest:(null==s?void 0:s.chDest)||{},chSource:(null==s?void 0:s.chSource)||{}}),U.currentCall.checkAcceptedUpdate({acceptedSocket:!0}),U.currentCall.addTransferCalls({type:"transferred",displayName:r.getDisplayName(s),number:"".concat(s.counterpartNum),startTime:"".concat(m.getTimestampInSeconds())}),c.store.getState().island.isFromStreaming&&"out"===s.direction&&setTimeout((function(){U.island.setIslandView("streamingAnswer")}),200),u.isPhysical()&&function(e){U.currentCall.updateCurrentCall({conversationId:e.id,accepted:!0,incoming:"in"!==e.direction&&void 0}),i.eventDispatch("phone-island-call-answered",{}),c.store.dispatch.player.stopAudioPlayer(),c.store.dispatch.player.setAudioPlayerLoop(!1)}(s),"call"===g&&l&&U.currentCall.updateCurrentCall({transferring:!1});if(p.length>1)U.currentCall.deleteTransferCalls();else if(s&&!s.connected){if(l&&!d){var T=p.find((function(e){return e.number===s.counterpartNum}));!s.connected&&T&&(U.currentCall.updateCurrentCall({transferring:!1}),i.eventDispatch("phone-island-call-transfer-failed",{}),U.currentCall.updateTransferSwitching(!1))}"REC"===(null==s?void 0:s.counterpartName)&&U.physicalRecorder.setRecordingTempVariable(!0)}s&&!s.connected&&"out"===s.direction&&U.currentCall.checkOutgoingUpdate({outgoingSocket:!0,outgoing:"REC"!==(null==s?void 0:s.counterpartName),displayName:r.getDisplayName(s),number:"".concat(null==s?void 0:s.counterpartNum),username:"".concat(h&&h[null==s?void 0:s.counterpartNum]&&h[null==s?void 0:s.counterpartNum].username)||""})}break;case"onhold":var x=s.counterpartName,I=s.counterpartNum,E=s.startTime;l&&I&&x&&"<unknown>"!==x&&(U.currentCall.addTransferCalls({type:"destination",displayName:r.getDisplayName(s),number:I,startTime:"".concat(m.getTimestampInSeconds())}),U.currentCall.updateCurrentCall({displayName:r.getDisplayName(s),number:I,startTime:"".concat(E/1e3),conversationId:s.id}),U.island.setIslandView("call"));break;case"busy_ringing":i.eventDispatch("phone-island-call-ringing",{})}}}else"online"==t.status&&v.userTotallyFree()&&(U.player.stopAudioPlayer(),U.currentCall.reset(),U.physicalRecorder.setRecordingTempVariable(!1),U.island.setIsFromStreaming(!1))};return x.current=t.io("https://"+k,{upgrade:!1,transports:["websocket"],reconnection:!0,reconnectionDelay:2e3}),U.websocket.update({socket:x.current}),x.current.on("connect",(function(){console.debug("Socket connected sid: ".concat(x.current.id)),i.eventDispatch("phone-island-socket-connected",{})})),x.current.on("disconnect",(function(e){console.debug("Socket disconnect - reason: ".concat(e)),e.includes("server disconnect")?i.eventDispatch("phone-island-server-disconnected",{}):i.eventDispatch("phone-island-socket-disconnected",{})})),x.current.io.on("error",(function(e){console.debug("Socket error: ",e)})),x.current.on("connect_error",(function(e){console.debug("Socket connect_error: ",e)})),x.current.io.on("reconnect",(function(e){i.eventDispatch("phone-island-socket-reconnected",{}),console.debug("Socket reconnect attemp ".concat(e," (sid: ").concat(x.current.id,")"))})),x.current.io.on("reconnect_attempt",(function(e){console.debug("Socket reconnect_attempt ".concat(e))})),x.current.io.on("reconnect_error",(function(e){console.debug("Socket reconnect_error: ",e)})),x.current.io.on("reconnect_failed",(function(){console.debug("Socket reconnect_failed")})),T.current=setInterval((function(){x.current.volatile.emit("ping",s.withTimeout((function(){U.alerts.removeAlert("socket_down"),i.eventDispatch("phone-island-alert-removed",{type:"socket_down"}),i.eventDispatch("phone-island-socket-disconnected-popup-close",{})}),(function(){U.alerts.setAlert("socket_down"),i.eventDispatch("phone-island-socket-disconnected-popup-open",{}),console.error("Socket is unreachable!")}),7e3))}),7e3),x.current.on("connect",(function(){console.debug("Socket on: "+k+" is connected!"),x.current.emit("login",{accessKeyId:"".concat(w),token:C,uaType:j})})),x.current.on("authe_ok",(function(){console.debug("Socket authentication success!"),i.eventDispatch("phone-island-socket-authorized",{})})),x.current.on("userMainPresenceUpdate",(function(n){c.store.dispatch.users.updateEndpointMainPresence(e.__assign({},n.mainPresence)),p.dispatchMainPresence(n)})),x.current.on("extenHangup",(function(e){var n=c.store.getState().currentUser,t=n.endpoints,r=n.username,o=c.store.getState().conference,s=o.isActive,a=o.conferenceStartedFrom,u=c.store.getState().island,l=u.view,d=u.previewCallFromMobileOrNethlink,p=((null==t?void 0:t.extension)||[]).find((function(n){return n.id===e.callerNum})),m=null==p?void 0:p.type;"normal_clearing"===e.cause&&("physical"===m||"mobile"===m)||"normal_clearing"===e.cause&&"webrtc"===m&&d||"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(){c.store.dispatch.island.toggleAvoidToShow(!1),c.store.dispatch.island.setPreviewCallFromMobileOrNethlink(!1)}),500),s&&a!==r&&c.store.dispatch.conference.resetConference()):"normal_circuit_congestion"===(null==e?void 0:e.cause)&&s&&a===r?i.eventDispatch("phone-island-view-changed",{viewType:"waitingConference"}):"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"!==m&&"nethlink"!==m||!s||a===r||c.store.dispatch.conference.resetConference(),"interworking"===(null==e?void 0:e.cause)&&s&&a===r&&"waitingConference"!==l&&i.eventDispatch("phone-island-view-changed",{viewType:"waitingConference"})})),x.current.on("extenConnected",(function(e){var n=c.store.getState().currentUser,t=n.default_device,r=n.endpoints,o=((null==r?void 0:r.extension)||[]).find((function(n){return n.id===e.extenConnected})),s=null==o?void 0:o.type;(("webrtc"===(null==t?void 0:t.type)||"nethlink"===(null==t?void 0:t.type))&&s&&("mobile"===s||"physical"===s)||"physical"===(null==t?void 0:t.type)&&s&&"physical"!==s)&&(c.store.dispatch.island.toggleAvoidToShow(!0),c.store.dispatch.island.setPreviewCallFromMobileOrNethlink(!0),i.eventDispatch("phone-island-call-answered",{extensionType:s}))})),x.current.on("extenUpdate",(function(e){var n,t;U.users.updateExtension(e);var r=c.store.getState().users.extensions,o={},i=c.store.getState().currentUser;for(var s in r){var a=r[s].username,u=r[s].exten;o[a]||(o[a]=[]),o[a].push(u)}var d=o[e.username],m=e.conversations[Object.keys(e.conversations)[0]]||{},v=!1;if((null==e?void 0:e.username)===w&&!l.isEmpty(m)&&(null==m?void 0:m.owner)){var g=null===(t=null===(n=null==i?void 0:i.endpoints)||void 0===n?void 0:n.extension)||void 0===t?void 0:t.find((function(e){return e.id===m.owner}));g&&"mobile"===g.type&&(v=!0)}if(p.dispatchExtensions(e),l.isEmpty(m)){var f=null==d?void 0:d.some((function(e){var n,t=null===(n=r[e])||void 0===n?void 0:n.conversations;return!l.isEmpty(t)}));f||p.dispatchConversations(e)}else v||p.dispatchConversations(e);v&&"busy"===(null==e?void 0:e.status)&&(null==e?void 0:e.username)===w&&(c.store.dispatch.island.toggleAvoidToShow(!0),c.store.dispatch.island.setPreviewCallFromMobileOrNethlink(!0)),e.username===w&&(h(e,m),U.currentUser.updateConversations(e))})),x.current.on("queueUpdate",(function(e){p.dispatchQueueUpdate(e)})),x.current.on("queueMemberUpdate",(function(e){p.dispatchQueueMemberUpdate(e)})),x.current.on("takeOver",(function(){p.dispatchAlreadyLogin()})),x.current.on("serverReloaded",(function(){p.dispatchServerReload()})),x.current.on("parkingUpdate",(function(){p.dispatchParkingUpdate()})),x.current.on("actionNethLink",(function(e,n){p.dispatchUrlCall(e,n)})),x.current.on("message",(function(e){switch(e.message){case"screenSharingStart":U.island.toggleSideViewVisible(!1),U.island.setIslandView("video"),U.screenShare.update({isJoiningScreenShare:!0,room:e.roomId});break;case"screenSharingStop":U.island.toggleSideViewVisible(!1),U.island.setIslandView("video"),U.screenShare.update({isLeavingScreenShare:!0});break;default:console.warn("Socket: unknown message type ",e.message)}})),x.current.on("updateDefaultDevice",(function(n){p.dispatchDefaultDeviceUpdate(n);var t=c.store.getState().users.extensions,r=c.store.getState().currentUser.endpoints;if(t&&r){var o=Object.values(t).filter((function(e){return(null==e?void 0:e.exten)===n}));if(0!==o.length){var i=o[0],s=r.extension.find((function(e){return e.id===i.exten}));s&&(i=e.__assign(e.__assign({},i),{type:s.type})),c.store.dispatch.currentUser.updateCurrentDefaultDevice(i),a.checkMediaPermissions()}}})),x.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,o=c.store.getState().conference.usersList,i=e.__assign({},r);o&&Object.keys(i).forEach((function(n){o[n]&&(i[n]=e.__assign(e.__assign({},i[n]),{muted:o[n].muted}))})),c.store.dispatch.conference.updateConferenceUsersList(i),c.store.dispatch.conference.updateConferenceId(t)}})),x.current.on("confBridgeEnd",(function(e){e&&(null==e?void 0:e.id)&&(c.store.dispatch.conference.resetConference(),i.eventDispatch("phone-island-conference-finished",{}))})),x.current.on("callWebrtc",(function(e){i.eventDispatch("phone-island-call-start",{number:e})})),x.current.on("newVoiceMessageCounter",(function(e){i.eventDispatch("phone-island-voicemail-received",{voicemailInfo:e})})),x.current.on("streamingSourceUpdate",(function(e){i.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){c.store.getState().island.isFromStreaming;var o=c.store.getState().currentCall.streamingSourceNumber;d.getStreamingSourceId(o),U.streaming.updateSourceImage({source:t,image:r})}}})),function(){clearInterval(T.current),x.current.close()}}),[k,w,C,j,U]),n.useEffect((function(){_&&(console.info("websocket reconnection"),x.current.disconnect(),x.current.connect(),N())}),[_]),y.default.createElement(y.default.Fragment,null,D)};
|
|
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("../lib/phone/conversation.js"),o=require("../services/user.js"),i=require("../utils/genericFunctions/eventDispatch.js"),s=require("../utils/genericFunctions/withTimeout.js"),c=require("../store/index.js");require("../lib/webrtc/janus.js"),require("../node_modules/webrtc-adapter/src/js/adapter_core.js");var a=require("../lib/devices/devices.js"),u=require("../lib/user/default_device.js"),l=require("../utils/genericFunctions/isEmpty.js"),d=require("../utils/streaming/getStreamingSourceId.js"),p=require("../events/SocketEvents.js"),m=require("../utils/genericFunctions/timestamp.js"),v=require("../lib/user/extensions.js"),g=require("../utils/streaming/isFromStreaming.js"),h=require("../node_modules/react-redux/es/hooks/useSelector.js");require("../node_modules/react-redux/es/components/Context.js"),require("../node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js"),require("../node_modules/react-redux/node_modules/react-is/index.js");var f=require("../node_modules/react-redux/es/hooks/useDispatch.js"),S=require("../lib/phone/trunk.js");function b(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var y=b(n);exports.Socket=function(b){var k=b.hostName,w=b.username,C=b.authToken,_=b.reload,N=b.reloadedCallback,D=b.children,j=b.uaType,U=f.useDispatch(),T=n.useRef(),x=n.useRef(),q=n.useRef(!1);h.useSelector((function(e){return e.currentUser}));return n.useEffect((function(){var n=function(e){if(e.counterpartNum&&g.isFromStreaming(e.counterpartNum)){U.island.setIsFromStreaming(!0),U.currentCall.updateCurrentCall({streamingSourceNumber:e.counterpartNum});var n=d.getStreamingSourceId(e.counterpartNum);n&&o.subscribe({id:n}).catch((function(e){return console.error("Error subscribing to streaming source:",e)}))}},h=function(t,s){var a=c.store.getState().currentCall,l=a.transferring,d=a.transferSwitching,p=a.transferCalls,g=c.store.getState().island.view;if(Object.keys(s).length>0){if(t.status){var h=c.store.getState().users.extensions,f=c.store.getState().currentUser.default_device,b=c.store.getState().currentUser,y=b.endpoints,k=b.username,w=c.store.getState().currentCall;w.incoming,w.outgoing;var C=function(){if(!h||!k)return!1;var e=Object.values(h).filter((function(e){return(null==e?void 0:e.username)===k}));return null==e?void 0:e.some((function(e){var n=null==y?void 0:y.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(t.status){case"ringing":if(n(s),"mobile"===j&&C()||"desktop"===j&&("webrtc"===(null==f?void 0:f.type)||void 0===(null==f?void 0:f.type)&&!C()||!C()&&"physical"===(null==f?void 0:f.type))){q.current||(q.current=!0,o.getCurrentUserInfo().then((function(n){n&&(U.currentUser.updateCurrentUser(n),i.eventDispatch("phone-island-user-informations-update",e.__assign({},n)),n.settings&&n.settings.open_param_url?U.paramUrl.setOpenParamUrlType(n.settings.open_param_url):U.paramUrl.setOpenParamUrlType("never"))})).catch((function(e){console.error("Error getting current user info:",e)})).finally((function(){setTimeout((function(){q.current=!1}),100)}))),U.currentCall.checkIncomingUpdatePlay({conversationId:s.id,displayName:r.getDisplayName(s),number:"".concat(s.counterpartNum),incomingSocket:!0,incoming:!0,username:"".concat(h&&h[s.counterpartNum]&&h[s.counterpartNum].username)||"",ownerExtension:s.owner}),s.id,r.getDisplayName(s),"".concat(s.counterpartNum),s.owner,"".concat(h&&h[s.counterpartNum]&&h[s.counterpartNum].username),null==s||s.chDest,null==s||s.chSource,s.direction,s.inConference,s.linkedId,s.uniqueId,s.throughQueue,s.throughTrunk,s.recording,c.store.dispatch.island.setIslandView("call"),i.eventDispatch("phone-island-call-ringing",{});var _=c.store.getState().paramUrl.openParamUrlType,N=c.store.getState().island.urlOpened;if("ringing"===_&&!N){var D=S.isFromTrunk(s.counterpartNum);c.store.dispatch.paramUrl.setThroughTrunk(D),c.store.dispatch.island.setUrlOpened(!1),i.eventDispatch("phone-island-url-parameter-opened",{counterpartNum:s.counterpartNum,counterpartName:r.getDisplayName(s),owner:s.owner,uniqueId:s.uniqueId,throughQueue:s.throughQueue,throughTrunk:D,direction:s.direction,connected:s.connected})}}break;case"busy":if(n(s),"mobile"===j&&C()||"desktop"===j&&("webrtc"===(null==f?void 0:f.type)||void 0===(null==f?void 0:f.type)&&!C()||!C()&&"physical"===(null==f?void 0:f.type))){if(s&&s.connected)U.currentCall.updateCurrentCall({conversationId:s.id,displayName:r.getDisplayName(s),number:"".concat(s.counterpartNum),ownerExtension:s.owner,username:"".concat(h&&h[s.counterpartNum]&&h[s.counterpartNum].username)||"",chDest:(null==s?void 0:s.chDest)||{},chSource:(null==s?void 0:s.chSource)||{}}),U.currentCall.checkAcceptedUpdate({acceptedSocket:!0}),U.currentCall.addTransferCalls({type:"transferred",displayName:r.getDisplayName(s),number:"".concat(s.counterpartNum),startTime:"".concat(m.getTimestampInSeconds())}),c.store.getState().island.isFromStreaming&&"out"===s.direction&&setTimeout((function(){U.island.setIslandView("streamingAnswer")}),200),u.isPhysical()&&function(e){U.currentCall.updateCurrentCall({conversationId:e.id,accepted:!0,incoming:"in"!==e.direction&&void 0}),i.eventDispatch("phone-island-call-answered",{}),c.store.dispatch.player.stopAudioPlayer(),c.store.dispatch.player.setAudioPlayerLoop(!1)}(s),"call"===g&&l&&U.currentCall.updateCurrentCall({transferring:!1});if(p.length>1)U.currentCall.deleteTransferCalls();else if(s&&!s.connected){if(l&&!d){var T=p.find((function(e){return e.number===s.counterpartNum}));!s.connected&&T&&(U.currentCall.updateCurrentCall({transferring:!1}),i.eventDispatch("phone-island-call-transfer-failed",{}),U.currentCall.updateTransferSwitching(!1))}"REC"===(null==s?void 0:s.counterpartName)&&U.physicalRecorder.setRecordingTempVariable(!0)}s&&!s.connected&&"out"===s.direction&&U.currentCall.checkOutgoingUpdate({outgoingSocket:!0,outgoing:"REC"!==(null==s?void 0:s.counterpartName),displayName:r.getDisplayName(s),number:"".concat(null==s?void 0:s.counterpartNum),username:"".concat(h&&h[null==s?void 0:s.counterpartNum]&&h[null==s?void 0:s.counterpartNum].username)||""})}break;case"onhold":var x=s.counterpartName,I=s.counterpartNum,E=s.startTime;l&&I&&x&&"<unknown>"!==x&&(U.currentCall.addTransferCalls({type:"destination",displayName:r.getDisplayName(s),number:I,startTime:"".concat(m.getTimestampInSeconds())}),U.currentCall.updateCurrentCall({displayName:r.getDisplayName(s),number:I,startTime:"".concat(E/1e3),conversationId:s.id}),U.island.setIslandView("call"));break;case"busy_ringing":i.eventDispatch("phone-island-call-ringing",{})}}}else"online"==t.status&&v.userTotallyFree()&&(U.player.stopAudioPlayer(),U.currentCall.reset(),U.physicalRecorder.setRecordingTempVariable(!1),U.island.setIsFromStreaming(!1))};return x.current=t.io("https://"+k,{upgrade:!1,transports:["websocket"],reconnection:!0,reconnectionDelay:2e3}),U.websocket.update({socket:x.current}),x.current.on("connect",(function(){console.debug("Socket connected sid: ".concat(x.current.id)),i.eventDispatch("phone-island-socket-connected",{})})),x.current.on("disconnect",(function(e){console.debug("Socket disconnect - reason: ".concat(e)),e.includes("server disconnect")?i.eventDispatch("phone-island-server-disconnected",{}):i.eventDispatch("phone-island-socket-disconnected",{})})),x.current.io.on("error",(function(e){console.debug("Socket error: ",e)})),x.current.on("connect_error",(function(e){console.debug("Socket connect_error: ",e)})),x.current.io.on("reconnect",(function(e){i.eventDispatch("phone-island-socket-reconnected",{}),console.debug("Socket reconnect attemp ".concat(e," (sid: ").concat(x.current.id,")"))})),x.current.io.on("reconnect_attempt",(function(e){console.debug("Socket reconnect_attempt ".concat(e))})),x.current.io.on("reconnect_error",(function(e){console.debug("Socket reconnect_error: ",e)})),x.current.io.on("reconnect_failed",(function(){console.debug("Socket reconnect_failed")})),T.current=setInterval((function(){x.current.volatile.emit("ping",s.withTimeout((function(){U.alerts.removeAlert("socket_down"),i.eventDispatch("phone-island-alert-removed",{type:"socket_down"}),i.eventDispatch("phone-island-socket-disconnected-popup-close",{})}),(function(){U.alerts.setAlert("socket_down"),i.eventDispatch("phone-island-socket-disconnected-popup-open",{}),console.error("Socket is unreachable!")}),7e3))}),7e3),x.current.on("connect",(function(){console.debug("Socket on: "+k+" is connected!"),x.current.emit("login",{accessKeyId:"".concat(w),token:C,uaType:j})})),x.current.on("authe_ok",(function(){console.debug("Socket authentication success!"),i.eventDispatch("phone-island-socket-authorized",{})})),x.current.on("userMainPresenceUpdate",(function(n){c.store.dispatch.users.updateEndpointMainPresence(e.__assign({},n.mainPresence)),p.dispatchMainPresence(n)})),x.current.on("extenHangup",(function(e){var n=c.store.getState().currentUser,t=n.endpoints,r=n.username,o=c.store.getState().conference,s=o.isActive,a=o.conferenceStartedFrom,u=c.store.getState().island,l=u.view,d=u.previewCallFromMobileOrNethlink,p=((null==t?void 0:t.extension)||[]).find((function(n){return n.id===e.callerNum})),m=null==p?void 0:p.type;"normal_clearing"===e.cause&&("physical"===m||"mobile"===m)||"normal_clearing"===e.cause&&("webrtc"===m||"nethlink"===m)&&d||"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(){c.store.dispatch.island.toggleAvoidToShow(!1),c.store.dispatch.island.setPreviewCallFromMobileOrNethlink(!1)}),500),s&&a!==r&&c.store.dispatch.conference.resetConference()):"normal_circuit_congestion"===(null==e?void 0:e.cause)&&s&&a===r?i.eventDispatch("phone-island-view-changed",{viewType:"waitingConference"}):"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"!==m&&"nethlink"!==m||!s||a===r||c.store.dispatch.conference.resetConference(),"interworking"===(null==e?void 0:e.cause)&&s&&a===r&&"waitingConference"!==l&&i.eventDispatch("phone-island-view-changed",{viewType:"waitingConference"})})),x.current.on("extenConnected",(function(e){var n=c.store.getState().currentUser,t=n.default_device,r=n.endpoints,o=((null==r?void 0:r.extension)||[]).find((function(n){return n.id===e.extenConnected})),s=null==o?void 0:o.type;(("webrtc"===(null==t?void 0:t.type)||"nethlink"===(null==t?void 0:t.type))&&s&&("mobile"===s||"physical"===s)||"physical"===(null==t?void 0:t.type)&&s&&"physical"!==s)&&(c.store.dispatch.island.toggleAvoidToShow(!0),c.store.dispatch.island.setPreviewCallFromMobileOrNethlink(!0),i.eventDispatch("phone-island-call-answered",{extensionType:s}))})),x.current.on("extenUpdate",(function(e){var n,t;U.users.updateExtension(e);var r=c.store.getState().users.extensions,o={},i=c.store.getState().currentUser;for(var s in r){var a=r[s].username,u=r[s].exten;o[a]||(o[a]=[]),o[a].push(u)}var d=o[e.username],m=e.conversations[Object.keys(e.conversations)[0]]||{},v=!1;if((null==e?void 0:e.username)===w&&!l.isEmpty(m)&&(null==m?void 0:m.owner)){var g=null===(t=null===(n=null==i?void 0:i.endpoints)||void 0===n?void 0:n.extension)||void 0===t?void 0:t.find((function(e){return e.id===m.owner}));g&&"mobile"===g.type&&(v=!0)}if(p.dispatchExtensions(e),l.isEmpty(m)){var f=null==d?void 0:d.some((function(e){var n,t=null===(n=r[e])||void 0===n?void 0:n.conversations;return!l.isEmpty(t)}));f||p.dispatchConversations(e)}else v||p.dispatchConversations(e);v&&"busy"===(null==e?void 0:e.status)&&(null==e?void 0:e.username)===w&&(c.store.dispatch.island.toggleAvoidToShow(!0),c.store.dispatch.island.setPreviewCallFromMobileOrNethlink(!0)),e.username===w&&(h(e,m),U.currentUser.updateConversations(e))})),x.current.on("queueUpdate",(function(e){p.dispatchQueueUpdate(e)})),x.current.on("queueMemberUpdate",(function(e){p.dispatchQueueMemberUpdate(e)})),x.current.on("takeOver",(function(){p.dispatchAlreadyLogin()})),x.current.on("serverReloaded",(function(){p.dispatchServerReload()})),x.current.on("parkingUpdate",(function(){p.dispatchParkingUpdate()})),x.current.on("actionNethLink",(function(e,n){p.dispatchUrlCall(e,n)})),x.current.on("message",(function(e){switch(e.message){case"screenSharingStart":U.island.toggleSideViewVisible(!1),U.island.setIslandView("video"),U.screenShare.update({isJoiningScreenShare:!0,room:e.roomId});break;case"screenSharingStop":U.island.toggleSideViewVisible(!1),U.island.setIslandView("video"),U.screenShare.update({isLeavingScreenShare:!0});break;default:console.warn("Socket: unknown message type ",e.message)}})),x.current.on("updateDefaultDevice",(function(n){p.dispatchDefaultDeviceUpdate(n);var t=c.store.getState().users.extensions,r=c.store.getState().currentUser.endpoints;if(t&&r){var o=Object.values(t).filter((function(e){return(null==e?void 0:e.exten)===n}));if(0!==o.length){var i=o[0],s=r.extension.find((function(e){return e.id===i.exten}));s&&(i=e.__assign(e.__assign({},i),{type:s.type})),c.store.dispatch.currentUser.updateCurrentDefaultDevice(i),a.checkMediaPermissions()}}})),x.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,o=c.store.getState().conference.usersList,i=e.__assign({},r);o&&Object.keys(i).forEach((function(n){o[n]&&(i[n]=e.__assign(e.__assign({},i[n]),{muted:o[n].muted}))})),c.store.dispatch.conference.updateConferenceUsersList(i),c.store.dispatch.conference.updateConferenceId(t)}})),x.current.on("confBridgeEnd",(function(e){e&&(null==e?void 0:e.id)&&(c.store.dispatch.conference.resetConference(),i.eventDispatch("phone-island-conference-finished",{}))})),x.current.on("callWebrtc",(function(e){i.eventDispatch("phone-island-call-start",{number:e})})),x.current.on("newVoiceMessageCounter",(function(e){i.eventDispatch("phone-island-voicemail-received",{voicemailInfo:e})})),x.current.on("streamingSourceUpdate",(function(e){i.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){c.store.getState().island.isFromStreaming;var o=c.store.getState().currentCall.streamingSourceNumber;d.getStreamingSourceId(o),U.streaming.updateSourceImage({source:t,image:r})}}})),function(){clearInterval(T.current),x.current.close()}}),[k,w,C,j,U]),n.useEffect((function(){_&&(console.info("websocket reconnection"),x.current.disconnect(),x.current.connect(),N())}),[_]),y.default.createElement(y.default.Fragment,null,D)};
|
|
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 { getDisplayName } from '../lib/phone/conversation'\nimport { getCurrentUserInfo } from '../services/user'\nimport {\n dispatchMainPresence,\n dispatchConversations,\n dispatchQueueUpdate,\n dispatchQueueMemberUpdate,\n dispatchAlreadyLogin,\n dispatchServerReload,\n dispatchParkingUpdate,\n dispatchExtensions,\n dispatchUrlCall,\n dispatchDefaultDeviceUpdate,\n} from '../events'\nimport { store } from '../store'\nimport { eventDispatch, withTimeout } from '../utils'\nimport type {\n ConversationTypes,\n ExtensionTypes,\n QueuesUpdateTypes,\n QueueUpdateMemberTypes,\n MainPresenceTypes,\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 } 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'\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\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\n // get user information\n const userInformation = useSelector((state: RootState) => state.currentUser)\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 const checkDefaultDeviceConversationClosed = (conv: any) => {\n // store.dispatch.player.stopAudioPlayer()\n store.dispatch.currentCall.reset()\n // store.dispatch.listen.reset()\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 /**\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 // 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 // Get updated user info\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 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 let callInformations = {\n conversationId: conv.id,\n displayName: getDisplayName(conv),\n counterpartNum: `${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 direction: conv.direction,\n inConference: conv.inConference,\n linkedId: conv.linkedId,\n uniqueId: conv.uniqueId,\n throughQueue: conv.throughQueue,\n throughTrunk: conv.throughTrunk,\n recording: conv.recording,\n }\n store.dispatch.island.setIslandView('call')\n\n eventDispatch('phone-island-call-ringing', {})\n const { openParamUrlType } = store.getState().paramUrl\n const { urlOpened } = store.getState().island\n\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 throughQueue: conv.throughQueue,\n throughTrunk: calculatedThroughTrunk,\n direction: conv.direction,\n connected: conv.connected,\n })\n }\n }\n break\n // @ts-ignore\n case 'busy':\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 // 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 // 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 socket.current = io('https://' + hostName, {\n upgrade: false,\n transports: ['websocket'],\n reconnection: true,\n reconnectionDelay: 2000,\n })\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 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 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 // Checks if socket is reachable every 5 seconds\n connectionCheckInterval.current = setInterval(() => {\n const start = Date.now()\n socket.current.volatile.emit(\n 'ping',\n withTimeout(\n () => {\n // Remove socket_down alert\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 },\n () => {\n // Set socket_down alert\n dispatch.alerts.setAlert('socket_down')\n eventDispatch('phone-island-socket-disconnected-popup-open', {})\n console.error('Socket is unreachable!')\n },\n 7 * 1000, // Waits for the response 7 seconds\n ),\n )\n }, 7 * 1000) // Executes a new check every 7 seconds\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\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\n // Find the extension type based on callerNum\n const connectedExtension = userExtensions.find((ext) => ext.id === res.callerNum)\n const extensionType: any = connectedExtension?.type\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' &&\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 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 eventDispatch('phone-island-view-changed', { viewType: 'waitingConference' })\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 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 eventDispatch('phone-island-view-changed', { viewType: 'waitingConference' })\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\n // Initialize conversation\n let conv = res.conversations[Object.keys(res.conversations)[0]] || {}\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 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 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 // `serverReload` is the socket event when server is reloaded\n socket.current.on('parkingUpdate', () => {\n // Dispatch serverReload event\n dispatchParkingUpdate()\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 socket.current.on('message', (data: any) => {\n switch (data.message) {\n case 'screenSharingStart':\n dispatch.island.toggleSideViewVisible(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.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\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('websocket reconnection')\n socket.current.disconnect()\n socket.current.connect()\n reloadedCallback()\n }\n }, [reload])\n\n return <>{children}</>\n}\n"],"names":["_a","hostName","username","authToken","reload","reloadedCallback","children","uaType","dispatch","useDispatch","connectionCheckInterval","useRef","socket","isUpdatingUserInfo","useSelector","state","currentUser","useEffect","handleStreamingSource","conv","counterpartNum","isFromStreaming","island","setIsFromStreaming","currentCall","updateCurrentCall","streamingSourceNumber","sourceId","getStreamingSourceId","subscribe","id","catch","error","console","handleCurrentUserEvents","res","store","getState","transferring","transferSwitching","transferCalls","view","Object","keys","length","status","extensions_1","users","extensions","default_device","_b","endpoints_1","endpoints","username_1","_c","incoming","hasOnlineNethlink","userExtensions","values","filter","ext","some","endpointExtension","extension","find","endpoint","exten","type","undefined","current","getCurrentUserInfo","then","userInfo","updateCurrentUser","eventDispatch","__assign","settings","open_param_url","paramUrl","setOpenParamUrlType","finally","setTimeout","checkIncomingUpdatePlay","conversationId","displayName","getDisplayName","number","concat","incomingSocket","ownerExtension","owner","chDest","chSource","direction","inConference","linkedId","uniqueId","throughQueue","throughTrunk","recording","setIslandView","openParamUrlType","urlOpened","calculatedThroughTrunk","isFromTrunk","setThroughTrunk","setUrlOpened","counterpartName","connected","checkAcceptedUpdate","acceptedSocket","addTransferCalls","startTime","getTimestampInSeconds","isPhysical","accepted","player","stopAudioPlayer","setAudioPlayerLoop","checkDefaultDeviceConversationActive","deleteTransferCalls","inTransferCalls","item","updateTransferSwitching","physicalRecorder","setRecordingTempVariable","checkOutgoingUpdate","outgoingSocket","outgoing","userTotallyFree","reset","io","upgrade","transports","reconnection","reconnectionDelay","websocket","update","on","debug","reason","includes","err","attempt","setInterval","volatile","emit","withTimeout","alerts","removeAlert","setAlert","accessKeyId","token","updateEndpointMainPresence","mainPresence","dispatchMainPresence","conference","isActive","conferenceStartedFrom","previewCallFromMobileOrNethlink","connectedExtension","callerNum","extensionType","cause","toggleAvoidToShow","setPreviewCallFromMobileOrNethlink","resetConference","viewType","extenConnected","updateExtension","deviceMap","userInformation","key","user","push","associatedExtensions","conversations","isMobileExtensionCall","isEmpty","matchingExtension","dispatchExtensions","hasNonEmptyConversation","extConversations","dispatchConversations","updateConversations","dispatchQueueUpdate","dispatchQueueMemberUpdate","dispatchAlreadyLogin","dispatchServerReload","dispatchParkingUpdate","link","urlType","dispatchUrlCall","data","message","toggleSideViewVisible","screenShare","isJoiningScreenShare","room","roomId","isLeavingScreenShare","warn","dispatchDefaultDeviceUpdate","extensionInformations","objectComplete","updateCurrentDefaultDevice","checkMediaPermissions","conferenceId","conferenceUsers","usersList_1","usersList","updatedConferenceUsers_1","forEach","userId","muted","updateConferenceUsersList","updateConferenceId","voicemailInfo","streamingData","streaming","source","image","updateSourceImage","clearInterval","close","info","disconnect","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 { getDisplayName } from '../lib/phone/conversation'\nimport { getCurrentUserInfo } from '../services/user'\nimport {\n dispatchMainPresence,\n dispatchConversations,\n dispatchQueueUpdate,\n dispatchQueueMemberUpdate,\n dispatchAlreadyLogin,\n dispatchServerReload,\n dispatchParkingUpdate,\n dispatchExtensions,\n dispatchUrlCall,\n dispatchDefaultDeviceUpdate,\n} from '../events'\nimport { store } from '../store'\nimport { eventDispatch, withTimeout } from '../utils'\nimport type {\n ConversationTypes,\n ExtensionTypes,\n QueuesUpdateTypes,\n QueueUpdateMemberTypes,\n MainPresenceTypes,\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 } 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'\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\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\n // get user information\n const userInformation = useSelector((state: RootState) => state.currentUser)\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 const checkDefaultDeviceConversationClosed = (conv: any) => {\n // store.dispatch.player.stopAudioPlayer()\n store.dispatch.currentCall.reset()\n // store.dispatch.listen.reset()\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 /**\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 // 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 // Get updated user info\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 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 let callInformations = {\n conversationId: conv.id,\n displayName: getDisplayName(conv),\n counterpartNum: `${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 direction: conv.direction,\n inConference: conv.inConference,\n linkedId: conv.linkedId,\n uniqueId: conv.uniqueId,\n throughQueue: conv.throughQueue,\n throughTrunk: conv.throughTrunk,\n recording: conv.recording,\n }\n store.dispatch.island.setIslandView('call')\n\n eventDispatch('phone-island-call-ringing', {})\n const { openParamUrlType } = store.getState().paramUrl\n const { urlOpened } = store.getState().island\n\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 throughQueue: conv.throughQueue,\n throughTrunk: calculatedThroughTrunk,\n direction: conv.direction,\n connected: conv.connected,\n })\n }\n }\n break\n // @ts-ignore\n case 'busy':\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 // 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 // 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 socket.current = io('https://' + hostName, {\n upgrade: false,\n transports: ['websocket'],\n reconnection: true,\n reconnectionDelay: 2000,\n })\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 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 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 // Checks if socket is reachable every 5 seconds\n connectionCheckInterval.current = setInterval(() => {\n const start = Date.now()\n socket.current.volatile.emit(\n 'ping',\n withTimeout(\n () => {\n // Remove socket_down alert\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 },\n () => {\n // Set socket_down alert\n dispatch.alerts.setAlert('socket_down')\n eventDispatch('phone-island-socket-disconnected-popup-open', {})\n console.error('Socket is unreachable!')\n },\n 7 * 1000, // Waits for the response 7 seconds\n ),\n )\n }, 7 * 1000) // Executes a new check every 7 seconds\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\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\n // Find the extension type based on callerNum\n const connectedExtension = userExtensions.find((ext) => ext.id === res.callerNum)\n const extensionType: any = connectedExtension?.type\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 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 eventDispatch('phone-island-view-changed', { viewType: 'waitingConference' })\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 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 eventDispatch('phone-island-view-changed', { viewType: 'waitingConference' })\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\n // Initialize conversation\n let conv = res.conversations[Object.keys(res.conversations)[0]] || {}\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 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 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 // `serverReload` is the socket event when server is reloaded\n socket.current.on('parkingUpdate', () => {\n // Dispatch serverReload event\n dispatchParkingUpdate()\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 socket.current.on('message', (data: any) => {\n switch (data.message) {\n case 'screenSharingStart':\n dispatch.island.toggleSideViewVisible(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.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\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('websocket reconnection')\n socket.current.disconnect()\n socket.current.connect()\n reloadedCallback()\n }\n }, [reload])\n\n return <>{children}</>\n}\n"],"names":["_a","hostName","username","authToken","reload","reloadedCallback","children","uaType","dispatch","useDispatch","connectionCheckInterval","useRef","socket","isUpdatingUserInfo","useSelector","state","currentUser","useEffect","handleStreamingSource","conv","counterpartNum","isFromStreaming","island","setIsFromStreaming","currentCall","updateCurrentCall","streamingSourceNumber","sourceId","getStreamingSourceId","subscribe","id","catch","error","console","handleCurrentUserEvents","res","store","getState","transferring","transferSwitching","transferCalls","view","Object","keys","length","status","extensions_1","users","extensions","default_device","_b","endpoints_1","endpoints","username_1","_c","incoming","hasOnlineNethlink","userExtensions","values","filter","ext","some","endpointExtension","extension","find","endpoint","exten","type","undefined","current","getCurrentUserInfo","then","userInfo","updateCurrentUser","eventDispatch","__assign","settings","open_param_url","paramUrl","setOpenParamUrlType","finally","setTimeout","checkIncomingUpdatePlay","conversationId","displayName","getDisplayName","number","concat","incomingSocket","ownerExtension","owner","chDest","chSource","direction","inConference","linkedId","uniqueId","throughQueue","throughTrunk","recording","setIslandView","openParamUrlType","urlOpened","calculatedThroughTrunk","isFromTrunk","setThroughTrunk","setUrlOpened","counterpartName","connected","checkAcceptedUpdate","acceptedSocket","addTransferCalls","startTime","getTimestampInSeconds","isPhysical","accepted","player","stopAudioPlayer","setAudioPlayerLoop","checkDefaultDeviceConversationActive","deleteTransferCalls","inTransferCalls","item","updateTransferSwitching","physicalRecorder","setRecordingTempVariable","checkOutgoingUpdate","outgoingSocket","outgoing","userTotallyFree","reset","io","upgrade","transports","reconnection","reconnectionDelay","websocket","update","on","debug","reason","includes","err","attempt","setInterval","volatile","emit","withTimeout","alerts","removeAlert","setAlert","accessKeyId","token","updateEndpointMainPresence","mainPresence","dispatchMainPresence","conference","isActive","conferenceStartedFrom","previewCallFromMobileOrNethlink","connectedExtension","callerNum","extensionType","cause","toggleAvoidToShow","setPreviewCallFromMobileOrNethlink","resetConference","viewType","extenConnected","updateExtension","deviceMap","userInformation","key","user","push","associatedExtensions","conversations","isMobileExtensionCall","isEmpty","matchingExtension","dispatchExtensions","hasNonEmptyConversation","extConversations","dispatchConversations","updateConversations","dispatchQueueUpdate","dispatchQueueMemberUpdate","dispatchAlreadyLogin","dispatchServerReload","dispatchParkingUpdate","link","urlType","dispatchUrlCall","data","message","toggleSideViewVisible","screenShare","isJoiningScreenShare","room","roomId","isLeavingScreenShare","warn","dispatchDefaultDeviceUpdate","extensionInformations","objectComplete","updateCurrentDefaultDevice","checkMediaPermissions","conferenceId","conferenceUsers","usersList_1","usersList","updatedConferenceUsers_1","forEach","userId","muted","updateConferenceUsersList","updateConferenceId","voicemailInfo","streamingData","streaming","source","image","updateSourceImage","clearInterval","close","info","disconnect","connect","React","createElement","Fragment"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../node_modules/tslib/tslib.es6.js"),t=require("react");require("../node_modules/react-redux/es/index.js");var r=require("../node_modules/webrtc-adapter/src/js/adapter_core.js"),n=require("../lib/webrtc/janus.js"),a=require("../lib/webrtc/messages.js"),i=require("../store/index.js"),o=require("../lib/devices/devices.js"),c=require("../lib/phone/call.js"),u=require("../lib/webrtc/connection.js"),s=require("../static/outgoing_ringtone.js"),l=require("../utils/customHooks/useEventListener.js"),d=require("../utils/genericFunctions/eventDispatch.js"),g=require("../lib/user/default_device.js"),v=require("../node_modules/react-redux/es/hooks/useDispatch.js");function p(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var f=p(t);exports.WebRTC=function(p){var m,b,h=p.hostName,w=p.sipExten,S=p.sipSecret,y=p.children,k=p.sipHost,C=p.sipPort,D=p.reload,T=p.uaType,E=p.reloadedCallback,j=v.useDispatch(),_=t.useRef(null),A=t.useRef(n.default),R={},L=t.useCallback((function(){A.current.init({debug:"all",dependencies:A.current.useDefaultDependencies({adapter:r.default}),callback:function(){var e=new A.current({server:"https://".concat(h,"/janus"),success:function(){e.attach&&e.attach({plugin:"janus.plugin.sip",opaqueId:"sebastian_"+(new Date).getTime(),success:function(e){e&&(j.webrtc.updateWebRTC({sipcall:e}),a.register({sipExten:w,sipSecret:S,sipHost:k,sipPort:C}),e&&A.current.log&&A.current.log("SIP plugin attached! ("+e.getPlugin()+", id = )"))},error:function(e){A.current.error&&(A.current.error(" -- Error attaching plugin..."),A.current.error(e))},consentDialog:function(e){A.current.log&&A.current.log("janus consentDialog (on: ".concat(e,")"))},webrtcState:function(e){A.current.log&&A.current.log("Janus says our WebRTC PeerConnection is "+(e?"up":"down")+" now")},iceState:function(e){i.store.getState().webrtc.sipcall&&A.current.log&&A.current.log('ICE state of PeerConnection of handle has changed to "'.concat(e,'"'))},mediaState:function(e,t){A.current.log&&A.current.log("Janus "+(t?"started":"stopped")+" receiving our "+e)},slowLink:function(e,t){e?A.current.warn&&A.current.warn("SLOW link: several missing packets from janus (".concat(t,")")):A.current.warn&&A.current.warn("SLOW link: janus is not receiving all your packets (".concat(t,")"))},onmessage:function(e,t){var r=i.store.getState().webrtc.sipcall;A.current.debug&&(A.current.debug(" ::: Got a message :::"),A.current.debug(JSON.stringify(e)));var n=e.error;if(null==n||null==n){var o=e.result;if(null!=o&&void 0!==o.event&&null!==o.event){var u=o.event,l=i.store.getState().recorder.recording,v=i.store.getState().island.view;switch(u){case"registration_failed":A.current.error&&A.current.error("Registration failed: "+o.code+" "+o.reason);break;case"unregistered":A.current.log&&A.current.log("Successfully un-registered as "+o.username+"!"),d.eventDispatch("phone-island-webrtc-unregistered",{});break;case"registered":A.current.log&&A.current.log("Successfully registered as "+o.username+"!"),d.eventDispatch("phone-island-webrtc-registered",{}),i.store.getState().webrtc.registered||i.store.dispatch.webrtc.updateWebRTC({registered:!0}),j.alerts.removeAlert("webrtc_down"),d.eventDispatch("phone-island-alert-removed",{type:"webrtc_down"}),j.webrtc.updateLastActivity((new Date).getTime());break;case"registering":A.current.log&&A.current.log("janus registering");break;case"calling":j.currentCall.checkOutgoingUpdate({outgoingWebRTC:!0}),j.webrtc.updateLastActivity((new Date).getTime());break;case"ringing":i.store.getState().player.audioPlayerPlaying||j.player.updateStartAudioPlayer({src:s.default,loop:!0}),j.webrtc.updateLastActivity((new Date).getTime()),"call"!==v&&j.island.setIslandView("call");break;case"progress":A.current.log&&A.current.log("There's early media from "+o.username+", wairing for the call!"),t&&a.handleRemote(t),j.webrtc.updateLastActivity((new Date).getTime());break;case"incomingcall":var p=i.store.getState().currentUser.default_device,f=i.store.getState().currentUser,m=f.endpoints,b=f.username,h=i.store.getState().users.extensions,w=function(){if(!h||!b)return!1;var e=Object.values(h).filter((function(e){return(null==e?void 0:e.username)===b}));return null==e?void 0:e.some((function(e){var t=null==m?void 0:m.extension.find((function(t){return t.id===(null==e?void 0:e.exten)}));return"nethlink"===(null==t?void 0:t.type)&&"offline"!==(null==e?void 0:e.status)}))};("mobile"===T&&w()||"desktop"===T&&("webrtc"===(null==p?void 0:p.type)||void 0===(null==p?void 0:p.type)&&!w()||!w()&&"physical"===(null==p?void 0:p.type)))&&(j.webrtc.updateWebRTC({jsepGlobal:t}),l?j.recorder.setIncoming(!0):(j.currentCall.checkIncomingUpdatePlay({incoming:!0,incomingWebRTC:!0}),A.current.log&&(j.currentCall.updateIncoming(!0),A.current.log("Incoming call from "+o.username+"!"))),j.webrtc.updateLastActivity((new Date).getTime()));break;case"accepted":var S=Math.floor(Date.now()/1e3);A.current.log&&A.current.log(o.username+" accepted the call!"),t&&a.handleRemote(t),j.currentCall.checkAcceptedUpdate({acceptedWebRTC:!0}),j.currentCall.updateCurrentCall({incoming:!1,incomingWebRTC:!1,startTime:null==S?void 0:S.toString()}),i.store.dispatch.player.stopAudioPlayer(),j.webrtc.updateLastActivity((new Date).getTime());break;case"hangup":l&&j.recorder.setRecording(!1),g.isPhysical()||"mobile"===T||(c.hangupCurrentCall(),r.hangup(),i.store.dispatch.player.stopAudioPlayer(),i.store.dispatch.currentCall.reset(),A.current.log&&A.current.log("Call hung up ("+o.code+" "+o.reason+")!"),j.webrtc.updateLastActivity((new Date).getTime())),i.store.dispatch.player.stopAudioPlayer();var y=i.store.getState().screenShare,k=y.active,C=y.plugin,D=y.localScreenStream,E=y.remoteScreenStream;k&&(A.current.stopAllTracks(D),A.current.stopAllTracks(E),j.screenShare.update({active:!1}),C.detach());break;case"gateway_down":console.warn("THE GATEWAY IS DOWN");break;case"info":"application/media_control+xml"===o.type&&o.content.includes("<picture_fast_update")&&r.send({message:{request:"keyframe",user:!0,peer:!0}});break;default:A.current.debug&&A.current.debug("Event not handled:",u)}}}else i.store.getState().webrtc.registered?(r&&r.hangup(),i.store.dispatch.player.stopAudioPlayer()):A.current.log&&A.current.log("User is not registered")},onlocaltrack:function(e,t){A.current.debug&&A.current.debug("Local track "+(t?"added":"removed")+":",e);var r=e.id.replace(/[{}]/g,"");if(!t){var n=R[r];if(n)try{var a=n.getTracks();for(var o in a){var c=a[o];c&&c.stop()}}catch(e){A.current.error&&A.current.error("Error removing track:",e)}return e.kind,void delete R[r]}var u=R[r];if(!u)if("audio"===e.kind)u=new MediaStream([e]),i.store.dispatch.webrtc.updateLocalAudioStream(u);else{u=new MediaStream([e]),i.store.dispatch.webrtc.updateLocalVideoStream(u),R[r]=u,A.current.debug&&A.current.debug("Created local stream:",u);var s=i.store.getState().player.localVideo;A.current.attachMediaStream&&s&&s.current&&A.current.attachMediaStream(s.current,u)}},onremotetrack:function(e,t,r){if(A.current.debug&&A.current.debug("Remote track (mid="+t+") "+(r?"added":"removed")+":",e),i.store.dispatch.player.stopAudioPlayer(),!r)return e.kind,void j.currentCall.updateCurrentCall({showRemoteVideoPlaceHolder:!0});if("audio"===e.kind){var n=new MediaStream([e]);A.current.debug&&A.current.debug("Created remote audio stream: "+n);var a=i.store.getState().player.remoteAudio;a&&a.current&&A.current.attachMediaStream&&A.current.attachMediaStream(a.current,n),i.store.dispatch.webrtc.updateRemoteAudioStream(n)}else{n=new MediaStream([e]);i.store.dispatch.webrtc.updateRemoteVideoStream(n),A.current.debug&&A.current.debug("Created remote video stream:"+n);var o=i.store.getState().player.largeRemoteVideo,c=i.store.getState().player.smallRemoteVideo;A.current.attachMediaStream&&o&&o.current&&A.current.attachMediaStream(o.current,n),A.current.attachMediaStream&&c&&c.current&&(A.current.attachMediaStream(c.current,n),j.currentCall.updateCurrentCall({showRemoteVideoPlaceHolder:!1}))}},oncleanup:function(){A.current.log&&A.current.log(" ::: janus Got a cleanup notification :::")}})},error:function(e){A.current.log&&A.current.log("error",e),j.alerts.setAlert("webrtc_down")},destroyed:function(){j.webrtc.updateWebRTC({destroyed:!0}),j.alerts.setAlert("webrtc_down")}});j.webrtc.updateWebRTC({janusInstance:e})}})}),[A.current]);t.useEffect((function(){void 0!==i.store.getState().currentUser.default_device&&o.checkMediaPermissions()}),[null===(b=null===(m=null===i.store||void 0===i.store?void 0:i.store.getState())||void 0===m?void 0:m.currentUser)||void 0===b?void 0:b.default_device]);var P=t.useState(navigator.onLine),M=P[0],I=P[1],q=t.useState(!1),W=q[0],x=q[1],V=t.useRef(!1);return t.useEffect((function(){var e=function(){return I(!0)},t=function(){return I(!1)};return window.addEventListener("online",e),window.addEventListener("offline",t),function(){window.removeEventListener("online",e),window.removeEventListener("offline",t)}}),[]),t.useEffect((function(){M?V.current&&(console.log("Internet connection restored."),x(!0),V.current=!1):(console.log("Internet connection lost."),V.current=!0,x(!1))}),[M]),t.useEffect((function(){var e;return L(),e=i.store.getState().webrtc.CHECK_INTERVAL_TIME,_.current||(_.current=setInterval((function(){return u.webrtcCheck((function(){a.register({sipExten:w,sipSecret:S,sipHost:k,sipPort:C})}))}),e)),function(){a.unregister(),clearInterval(_.current)}}),[]),t.useEffect((function(){if(D||W){a.unregister();var e=i.store.getState().webrtc.sipcall;e&&e.detach(),A.current.destroy&&A.current.destroy(),setTimeout((function(){L(),E&&E()}),1e4)}}),[D,W]),t.useEffect((function(){var e,t=function(){var e;navigator&&(null===navigator||void 0===navigator?void 0:navigator.mediaDevices)&&(null===(e=null===navigator||void 0===navigator?void 0:navigator.mediaDevices)||void 0===e?void 0:e.enumerateDevices)?null===navigator||void 0===navigator||navigator.mediaDevices.enumerateDevices().then((function(e){j.mediaDevices.updateMediaDevices(e)})).catch((function(e){console.error("Error fetching devices:",e)})):(console.warn("MediaDevices API not supported in this browser or context"),j.mediaDevices.updateMediaDevices([]))};if(t(),navigator&&(null===navigator||void 0===navigator?void 0:navigator.mediaDevices))return null===(e=null===navigator||void 0===navigator?void 0:navigator.mediaDevices)||void 0===e||e.addEventListener("devicechange",t),function(){var e;null===(e=null===navigator||void 0===navigator?void 0:navigator.mediaDevices)||void 0===e||e.removeEventListener("devicechange",t)}}),[]),l.useEventListener("phone-island-attach",(function(e){L(),d.eventDispatch("phone-island-attached",{})})),l.useEventListener("phone-island-call-transfer",(function(t){var r=null==t?void 0:t.to;j.island.toggleIsOpen(!0),function(t){e.__awaiter(this,void 0,void 0,(function(){return e.__generator(this,(function(e){switch(e.label){case 0:return[4,c.attendedTransfer(t)];case 1:return e.sent()&&(j.currentCall.updateCurrentCall({transferring:!0,paused:!1}),j.player.playRemoteAudio()),[2]}}))}))}(r),d.eventDispatch("phone-island-call-transfer-opened",{})})),f.default.createElement(f.default.Fragment,null,y)};
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../node_modules/tslib/tslib.es6.js"),t=require("react");require("../node_modules/react-redux/es/index.js");var r=require("../node_modules/webrtc-adapter/src/js/adapter_core.js"),n=require("../lib/webrtc/janus.js"),a=require("../lib/webrtc/messages.js"),i=require("../store/index.js"),c=require("../lib/devices/devices.js"),o=require("../lib/phone/call.js"),u=require("../lib/webrtc/connection.js"),s=require("../static/outgoing_ringtone.js"),l=require("../utils/customHooks/useEventListener.js"),d=require("../utils/genericFunctions/eventDispatch.js"),g=require("../utils/genericFunctions/localStorage.js"),v=require("../lib/user/default_device.js"),p=require("../node_modules/react-redux/es/hooks/useDispatch.js");function f(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var m=f(t);exports.WebRTC=function(f){var b,h,w=f.hostName,S=f.sipExten,y=f.sipSecret,k=f.children,C=f.sipHost,D=f.sipPort,_=f.reload,E=f.uaType,T=f.reloadedCallback,j=p.useDispatch(),A=t.useRef(null),I=t.useRef(n.default),R={},L=t.useCallback((function(){I.current.init({debug:"all",dependencies:I.current.useDefaultDependencies({adapter:r.default}),callback:function(){var t=new I.current({server:"https://".concat(w,"/janus"),success:function(){t.attach&&t.attach({plugin:"janus.plugin.sip",opaqueId:"sebastian_"+(new Date).getTime(),success:function(e){e&&(j.webrtc.updateWebRTC({sipcall:e}),a.register({sipExten:S,sipSecret:y,sipHost:C,sipPort:D}),e&&I.current.log&&I.current.log("SIP plugin attached! ("+e.getPlugin()+", id = )"))},error:function(e){I.current.error&&(I.current.error(" -- Error attaching plugin..."),I.current.error(e))},consentDialog:function(e){I.current.log&&I.current.log("janus consentDialog (on: ".concat(e,")"))},webrtcState:function(e){I.current.log&&I.current.log("Janus says our WebRTC PeerConnection is "+(e?"up":"down")+" now")},iceState:function(e){i.store.getState().webrtc.sipcall&&I.current.log&&I.current.log('ICE state of PeerConnection of handle has changed to "'.concat(e,'"'))},mediaState:function(e,t){I.current.log&&I.current.log("Janus "+(t?"started":"stopped")+" receiving our "+e)},slowLink:function(e,t){e?I.current.warn&&I.current.warn("SLOW link: several missing packets from janus (".concat(t,")")):I.current.warn&&I.current.warn("SLOW link: janus is not receiving all your packets (".concat(t,")"))},onmessage:function(e,t){var r=i.store.getState().webrtc.sipcall;I.current.debug&&(I.current.debug(" ::: Got a message :::"),I.current.debug(JSON.stringify(e)));var n=e.error;if(null==n||null==n){var c=e.result;if(null!=c&&void 0!==c.event&&null!==c.event){var u=c.event,l=i.store.getState().recorder.recording,g=i.store.getState().island.view;switch(u){case"registration_failed":I.current.error&&I.current.error("Registration failed: "+c.code+" "+c.reason);break;case"unregistered":I.current.log&&I.current.log("Successfully un-registered as "+c.username+"!"),d.eventDispatch("phone-island-webrtc-unregistered",{});break;case"registered":I.current.log&&I.current.log("Successfully registered as "+c.username+"!"),d.eventDispatch("phone-island-webrtc-registered",{}),i.store.getState().webrtc.registered||i.store.dispatch.webrtc.updateWebRTC({registered:!0}),j.alerts.removeAlert("webrtc_down"),d.eventDispatch("phone-island-alert-removed",{type:"webrtc_down"}),j.webrtc.updateLastActivity((new Date).getTime());break;case"registering":I.current.log&&I.current.log("janus registering");break;case"calling":j.currentCall.checkOutgoingUpdate({outgoingWebRTC:!0}),j.webrtc.updateLastActivity((new Date).getTime());break;case"ringing":i.store.getState().player.audioPlayerPlaying||j.player.updateStartAudioPlayer({src:s.default,loop:!0}),j.webrtc.updateLastActivity((new Date).getTime()),"call"!==g&&j.island.setIslandView("call");break;case"progress":I.current.log&&I.current.log("There's early media from "+c.username+", wairing for the call!"),t&&a.handleRemote(t),j.webrtc.updateLastActivity((new Date).getTime());break;case"incomingcall":var p=i.store.getState().currentUser.default_device,f=i.store.getState().currentUser,m=f.endpoints,b=f.username,h=i.store.getState().users.extensions,w=function(){if(!h||!b)return!1;var e=Object.values(h).filter((function(e){return(null==e?void 0:e.username)===b}));return null==e?void 0:e.some((function(e){var t=null==m?void 0:m.extension.find((function(t){return t.id===(null==e?void 0:e.exten)}));return"nethlink"===(null==t?void 0:t.type)&&"offline"!==(null==e?void 0:e.status)}))};("mobile"===E&&w()||"desktop"===E&&("webrtc"===(null==p?void 0:p.type)||void 0===(null==p?void 0:p.type)&&!w()||!w()&&"physical"===(null==p?void 0:p.type)))&&(j.webrtc.updateWebRTC({jsepGlobal:t}),l?j.recorder.setIncoming(!0):(j.currentCall.checkIncomingUpdatePlay({incoming:!0,incomingWebRTC:!0}),I.current.log&&(j.currentCall.updateIncoming(!0),I.current.log("Incoming call from "+c.username+"!"))),j.webrtc.updateLastActivity((new Date).getTime()));break;case"accepted":var S=Math.floor(Date.now()/1e3);I.current.log&&I.current.log(c.username+" accepted the call!"),t&&a.handleRemote(t),j.currentCall.checkAcceptedUpdate({acceptedWebRTC:!0}),j.currentCall.updateCurrentCall({incoming:!1,incomingWebRTC:!1,startTime:null==S?void 0:S.toString()}),i.store.dispatch.player.stopAudioPlayer(),j.webrtc.updateLastActivity((new Date).getTime());break;case"hangup":l&&j.recorder.setRecording(!1),v.isPhysical()||"mobile"===E||(o.hangupCurrentCall(),r.hangup(),i.store.dispatch.player.stopAudioPlayer(),i.store.dispatch.currentCall.reset(),I.current.log&&I.current.log("Call hung up ("+c.code+" "+c.reason+")!"),j.webrtc.updateLastActivity((new Date).getTime())),i.store.dispatch.player.stopAudioPlayer();var y=i.store.getState().screenShare,k=y.active,C=y.plugin,D=y.localScreenStream,_=y.remoteScreenStream;k&&(I.current.stopAllTracks(D),I.current.stopAllTracks(_),j.screenShare.update({active:!1}),C.detach());break;case"gateway_down":console.warn("THE GATEWAY IS DOWN");break;case"info":"application/media_control+xml"===c.type&&c.content.includes("<picture_fast_update")&&r.send({message:{request:"keyframe",user:!0,peer:!0}});break;default:I.current.debug&&I.current.debug("Event not handled:",u)}}}else i.store.getState().webrtc.registered?(r&&r.hangup(),i.store.dispatch.player.stopAudioPlayer()):I.current.log&&I.current.log("User is not registered")},onlocaltrack:function(e,t){I.current.debug&&I.current.debug("Local track "+(t?"added":"removed")+":",e);var r=e.id.replace(/[{}]/g,"");if(!t){var n=R[r];if(n)try{var a=n.getTracks();for(var c in a){var o=a[c];o&&o.stop()}}catch(e){I.current.error&&I.current.error("Error removing track:",e)}return e.kind,void delete R[r]}var u=R[r];if(!u)if("audio"===e.kind)u=new MediaStream([e]),i.store.dispatch.webrtc.updateLocalAudioStream(u);else{u=new MediaStream([e]),i.store.dispatch.webrtc.updateLocalVideoStream(u),R[r]=u,I.current.debug&&I.current.debug("Created local stream:",u);var s=i.store.getState().player.localVideo;I.current.attachMediaStream&&s&&s.current&&I.current.attachMediaStream(s.current,u)}},onremotetrack:function(t,r,n){var a=this;if(I.current.debug&&I.current.debug("Remote track (mid="+r+") "+(n?"added":"removed")+":",t),i.store.dispatch.player.stopAudioPlayer(),!n)return t.kind,void j.currentCall.updateCurrentCall({showRemoteVideoPlaceHolder:!0});if("audio"===t.kind){var c=new MediaStream([t]);I.current.debug&&I.current.debug("Created remote audio stream: "+c);var o=i.store.getState().player.remoteAudio;if(o&&o.current&&I.current.attachMediaStream){I.current.attachMediaStream(o.current,c);var u=g.getJSONItem("phone-island-audio-output-device");if(null==u?void 0:u.deviceId){e.__awaiter(a,void 0,void 0,(function(){var t,r,n,a,i;return e.__generator(this,(function(e){switch(e.label){case 0:if(!(t=u.deviceId)||"default"===t)return[3,4];e.label=1;case 1:return e.trys.push([1,3,,4]),[4,navigator.mediaDevices.enumerateDevices()];case 2:return r=e.sent(),r.filter((function(e){return"audiooutput"===e.kind})).some((function(e){return e.deviceId===t}))||(console.warn("Saved audio device ".concat(t," no longer available, using default device")),t="default",g.setJSONItem("phone-island-audio-output-device",{deviceId:"default"})),[3,4];case 3:return n=e.sent(),console.warn("Error checking device availability, using default:",n),t="default",[3,4];case 4:return e.trys.push([4,6,,11]),[4,o.current.setSinkId(t)];case 5:return e.sent(),console.info("Audio output device applied successfully to new stream:",t),[3,11];case 6:if(a=e.sent(),console.warn("Failed to apply audio output device to new stream:",a),"default"===t)return[3,10];e.label=7;case 7:return e.trys.push([7,9,,10]),[4,o.current.setSinkId("default")];case 8:return e.sent(),g.setJSONItem("phone-island-audio-output-device",{deviceId:"default"}),console.info("Fallback to default device successful"),[3,10];case 9:return i=e.sent(),console.error("Even default device failed:",i),[3,10];case 10:return[3,11];case 11:return[2]}}))}))}}i.store.dispatch.webrtc.updateRemoteAudioStream(c)}else{c=new MediaStream([t]);i.store.dispatch.webrtc.updateRemoteVideoStream(c),I.current.debug&&I.current.debug("Created remote video stream:"+c);var s=i.store.getState().player.largeRemoteVideo,l=i.store.getState().player.smallRemoteVideo;I.current.attachMediaStream&&s&&s.current&&I.current.attachMediaStream(s.current,c),I.current.attachMediaStream&&l&&l.current&&(I.current.attachMediaStream(l.current,c),j.currentCall.updateCurrentCall({showRemoteVideoPlaceHolder:!1}))}},oncleanup:function(){I.current.log&&I.current.log(" ::: janus Got a cleanup notification :::")}})},error:function(e){I.current.log&&I.current.log("error",e),j.alerts.setAlert("webrtc_down")},destroyed:function(){j.webrtc.updateWebRTC({destroyed:!0}),j.alerts.setAlert("webrtc_down")}});j.webrtc.updateWebRTC({janusInstance:t})}})}),[I.current]);t.useEffect((function(){void 0!==i.store.getState().currentUser.default_device&&c.checkMediaPermissions()}),[null===(h=null===(b=null===i.store||void 0===i.store?void 0:i.store.getState())||void 0===b?void 0:b.currentUser)||void 0===h?void 0:h.default_device]);var P=t.useState(navigator.onLine),M=P[0],q=P[1],W=t.useState(!1),x=W[0],O=W[1],V=t.useRef(!1);return t.useEffect((function(){var e=function(){return q(!0)},t=function(){return q(!1)};return window.addEventListener("online",e),window.addEventListener("offline",t),function(){window.removeEventListener("online",e),window.removeEventListener("offline",t)}}),[]),t.useEffect((function(){M?V.current&&(console.log("Internet connection restored."),O(!0),V.current=!1):(console.log("Internet connection lost."),V.current=!0,O(!1))}),[M]),t.useEffect((function(){var e;return L(),e=i.store.getState().webrtc.CHECK_INTERVAL_TIME,A.current||(A.current=setInterval((function(){return u.webrtcCheck((function(){a.register({sipExten:S,sipSecret:y,sipHost:C,sipPort:D})}))}),e)),function(){a.unregister(),clearInterval(A.current)}}),[]),t.useEffect((function(){if(_||x){a.unregister();var e=i.store.getState().webrtc.sipcall;e&&e.detach(),I.current.destroy&&I.current.destroy(),setTimeout((function(){L(),T&&T()}),1e4)}}),[_,x]),t.useEffect((function(){var e,t=function(){var e;navigator&&(null===navigator||void 0===navigator?void 0:navigator.mediaDevices)&&(null===(e=null===navigator||void 0===navigator?void 0:navigator.mediaDevices)||void 0===e?void 0:e.enumerateDevices)?null===navigator||void 0===navigator||navigator.mediaDevices.enumerateDevices().then((function(e){j.mediaDevices.updateMediaDevices(e)})).catch((function(e){console.error("Error fetching devices:",e)})):(console.warn("MediaDevices API not supported in this browser or context"),j.mediaDevices.updateMediaDevices([]))};if(t(),navigator&&(null===navigator||void 0===navigator?void 0:navigator.mediaDevices))return null===(e=null===navigator||void 0===navigator?void 0:navigator.mediaDevices)||void 0===e||e.addEventListener("devicechange",t),function(){var e;null===(e=null===navigator||void 0===navigator?void 0:navigator.mediaDevices)||void 0===e||e.removeEventListener("devicechange",t)}}),[]),l.useEventListener("phone-island-attach",(function(e){L(),d.eventDispatch("phone-island-attached",{})})),l.useEventListener("phone-island-call-transfer",(function(t){var r=null==t?void 0:t.to;j.island.toggleIsOpen(!0),function(t){e.__awaiter(this,void 0,void 0,(function(){return e.__generator(this,(function(e){switch(e.label){case 0:return[4,o.attendedTransfer(t)];case 1:return e.sent()&&(j.currentCall.updateCurrentCall({transferring:!0,paused:!1}),j.player.playRemoteAudio()),[2]}}))}))}(r),d.eventDispatch("phone-island-call-transfer-opened",{})})),m.default.createElement(m.default.Fragment,null,k)};
|
|
2
2
|
//# sourceMappingURL=WebRTC.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebRTC.js","sources":["../../src/components/WebRTC.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, useCallback, useState } from 'react'\nimport { useDispatch } from 'react-redux'\nimport { Dispatch } from '../store'\nimport adapter from 'webrtc-adapter'\nimport JanusLib from '../lib/webrtc/janus.js'\nimport type { JanusTypes } from '../types'\nimport { register, unregister, handleRemote } from '../lib/webrtc/messages'\nimport { store } from '../store'\nimport { checkMediaPermissions } from '../lib/devices/devices'\nimport { attendedTransfer, hangupCurrentCall } from '../lib/phone/call'\nimport { webrtcCheck } from '../lib/webrtc/connection'\nimport outgoingRingtone from '../static/outgoing_ringtone'\nimport { eventDispatch, useEventListener } from '../utils'\nimport { isPhysical } from '../lib/user/default_device'\n\ninterface WebRTCProps {\n children: ReactNode\n sipExten: string\n sipSecret: string\n hostName: string\n sipHost: string\n sipPort: string\n reload: boolean\n uaType: string\n reloadedCallback?: () => void\n}\n\nexport const WebRTC: FC<WebRTCProps> = ({\n hostName,\n sipExten,\n sipSecret,\n children,\n sipHost,\n sipPort,\n reload,\n uaType,\n reloadedCallback,\n}) => {\n // Initialize store dispatch\n const dispatch = useDispatch<Dispatch>()\n\n // Initialize janus check interval id\n const janusCheckInterval = useRef<any>(null)\n\n // Initialize Janus from Janus library\n const janus = useRef<JanusTypes>(JanusLib)\n\n let localTracks = {}\n let localVideos = 0\n let remoteTracks = {}\n let remoteVideos = 0\n\n // Initializes the webrtc connection and handlers\n const initWebRTC = useCallback(() => {\n janus.current.init({\n debug: 'all',\n dependencies: janus.current.useDefaultDependencies({\n adapter,\n }),\n callback: function () {\n const janusInstance = new janus.current({\n server: `https://${hostName}/janus`,\n success: () => {\n if (janusInstance.attach) {\n // Use Janus Sip Plugin\n janusInstance.attach({\n plugin: 'janus.plugin.sip',\n opaqueId: 'sebastian' + '_' + new Date().getTime(),\n success: function (pluginHandle) {\n // Set sipcall to the store\n if (pluginHandle) {\n dispatch.webrtc.updateWebRTC({\n sipcall: pluginHandle,\n })\n // Register the extension to the server\n register({ sipExten, sipSecret, sipHost, sipPort })\n if (pluginHandle) {\n if (janus.current.log)\n janus.current.log(\n 'SIP plugin attached! (' + pluginHandle.getPlugin() + ', id = ' + ')',\n )\n }\n }\n },\n error: function (error) {\n if (janus.current.error) {\n janus.current.error(' -- Error attaching plugin...')\n janus.current.error(error)\n }\n // reject()\n },\n consentDialog: function (on) {\n if (janus.current.log) janus.current.log(`janus consentDialog (on: ${on})`)\n },\n webrtcState: function (on) {\n if (janus.current.log)\n janus.current.log(\n 'Janus says our WebRTC PeerConnection is ' + (on ? 'up' : 'down') + ' now',\n )\n },\n iceState: function (newState) {\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n\n if (sipcall) {\n if (janus.current.log)\n janus.current.log(\n `ICE state of PeerConnection of handle has changed to \"${newState}\"`,\n )\n }\n },\n mediaState: function (medium, on) {\n if (janus.current.log)\n janus.current.log(\n 'Janus ' + (on ? 'started' : 'stopped') + ' receiving our ' + medium,\n )\n },\n slowLink: function (uplink, count) {\n if (uplink) {\n if (janus.current.warn)\n janus.current.warn(`SLOW link: several missing packets from janus (${count})`)\n } else {\n if (janus.current.warn)\n janus.current.warn(\n `SLOW link: janus is not receiving all your packets (${count})`,\n )\n }\n },\n onmessage: function (msg, jsep) {\n // Get webrtc state\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n\n if (janus.current.debug) {\n janus.current.debug(' ::: Got a message :::')\n janus.current.debug(JSON.stringify(msg))\n }\n\n // Handle errors in message\n var error = msg['error']\n if (error != null && error != undefined) {\n if (!store.getState().webrtc.registered) {\n if (janus.current.log) janus.current.log('User is not registered')\n } else {\n // Reset status\n sipcall && sipcall.hangup()\n\n // Stop the local audio element ringing\n store.dispatch.player.stopAudioPlayer()\n }\n return\n }\n // Manage events\n var result = msg['result']\n if (\n result !== null &&\n result !== undefined &&\n result['event'] !== undefined &&\n result['event'] !== null\n ) {\n // Get event data\n var event = result['event']\n\n // Get the recording state\n const { recording } = store.getState().recorder\n const { view } = store.getState().island\n\n // Manage different types of events\n switch (event) {\n case 'registration_failed':\n if (janus.current.error)\n janus.current.error(\n 'Registration failed: ' + result['code'] + ' ' + result['reason'],\n )\n break\n\n case 'unregistered':\n if (janus.current.log)\n janus.current.log(\n 'Successfully un-registered as ' + result['username'] + '!',\n )\n eventDispatch('phone-island-webrtc-unregistered', {})\n break\n\n case 'registered':\n if (janus.current.log)\n janus.current.log(\n 'Successfully registered as ' + result['username'] + '!',\n )\n eventDispatch('phone-island-webrtc-registered', {})\n if (!store.getState().webrtc.registered) {\n store.dispatch.webrtc.updateWebRTC({\n registered: true,\n })\n }\n // Remove WebRTC connections alert if any\n dispatch.alerts.removeAlert('webrtc_down')\n eventDispatch('phone-island-alert-removed', {\n type: 'webrtc_down',\n })\n // Update webrtc lastActivity time\n dispatch.webrtc.updateLastActivity(new Date().getTime())\n break\n\n case 'registering':\n if (janus.current.log) {\n janus.current.log('janus registering')\n }\n break\n\n // This event arrive on outgoing call start\n case 'calling':\n // Number and display name are updated inside socket\n dispatch.currentCall.checkOutgoingUpdate({\n outgoingWebRTC: true,\n })\n\n // Update webrtc last activity time\n dispatch.webrtc.updateLastActivity(new Date().getTime())\n break\n\n // After an outgoing call start on 180 code, it means\n // ...that the local outgoing ringtone must be player\n case 'ringing':\n const { audioPlayerPlaying } = store.getState().player\n\n // Check if the local audio is already playing and start playing\n if (!audioPlayerPlaying) {\n // Update audio player and start playing\n dispatch.player.updateStartAudioPlayer({\n src: outgoingRingtone,\n loop: true,\n })\n }\n // Update webrtc lastActivity time\n dispatch.webrtc.updateLastActivity(new Date().getTime())\n if (view !== 'call') {\n dispatch.island.setIslandView('call')\n }\n break\n\n // After an outgoing call start on 183 code, it means\n // ...that the outgoing ringtone arrives from the stream\n // ...playing the local outgoing ringtone isn't needed\n case 'progress':\n if (janus.current.log) {\n janus.current.log(\n \"There's early media from \" +\n result['username'] +\n ', wairing for the call!',\n )\n }\n // Set the remote description to janus lib\n if (jsep) {\n handleRemote(jsep)\n }\n // Update webrtc lastActivity time\n dispatch.webrtc.updateLastActivity(new Date().getTime())\n break\n\n case 'incomingcall':\n const { default_device } = store.getState().currentUser\n const { endpoints, username } = store.getState().currentUser\n const { extensions } = store.getState().users\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 (\n endpointExtension?.type === 'nethlink' && ext?.status !== 'offline'\n )\n })\n }\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 // Update webrtc state\n dispatch.webrtc.updateWebRTC({ jsepGlobal: jsep })\n // Check if is recording an audio through call\n // ...recording an audio is a request made by the user\n // ...it must be managed differently than an incoming call\n if (recording) {\n // Update the recorder state\n dispatch.recorder.setIncoming(true)\n } else {\n // Manage the incoming message as a webrtc call\n // Update incoming webrtc state, number and display name\n // ...are updated inside socket\n dispatch.currentCall.checkIncomingUpdatePlay({\n incoming: true,\n incomingWebRTC: true,\n })\n\n if (janus.current.log) {\n dispatch.currentCall.updateIncoming(true)\n janus.current.log('Incoming call from ' + result['username'] + '!')\n }\n }\n\n // Update the webrtc last activity time\n dispatch.webrtc.updateLastActivity(new Date().getTime())\n }\n\n break\n\n case 'accepted':\n const acceptedTimestamp = Math.floor(Date.now() / 1000)\n if (janus.current.log) {\n janus.current.log(result['username'] + ' accepted the call!')\n }\n // Set the remote description to janus lib\n if (jsep) {\n handleRemote(jsep)\n }\n // Set current call accepted\n dispatch.currentCall.checkAcceptedUpdate({\n acceptedWebRTC: true,\n })\n\n // Set incoming value to false and set start time\n dispatch.currentCall.updateCurrentCall({\n incoming: false,\n incomingWebRTC: false,\n startTime: acceptedTimestamp?.toString(),\n })\n\n // Stop the local audio element ringing\n store.dispatch.player.stopAudioPlayer()\n\n // Update webrtc lastActivity time\n dispatch.webrtc.updateLastActivity(new Date().getTime())\n break\n\n case 'hangup':\n // Manage hangup message during recording\n if (recording) {\n dispatch.recorder.setRecording(false)\n }\n if (!isPhysical() && uaType !== 'mobile') {\n hangupCurrentCall()\n sipcall.hangup()\n\n // Stop the local audio element ringing\n store.dispatch.player.stopAudioPlayer()\n\n // Check the janus doc before enable the following\n // if (\n // result['code'] === 486 &&\n // result['event'] === 'hangup' &&\n // result['reason'] === 'Busy Here'\n // ) {\n // dispatch.player.updateAudioSource({\n // src: busyRingtone,\n // })\n // dispatch.player.playAudio()\n // }\n // Reset current call info\n store.dispatch.currentCall.reset()\n if (janus.current.log)\n janus.current.log(\n 'Call hung up (' + result['code'] + ' ' + result['reason'] + ')!',\n )\n // Update webrtc lastActivity time\n dispatch.webrtc.updateLastActivity(new Date().getTime())\n // stopScreenSharingI()\n }\n\n // Stop the local audio element ringing\n store.dispatch.player.stopAudioPlayer()\n\n // Stop screen sharing if active\n const {\n active: screenShareActive,\n plugin,\n localScreenStream,\n remoteScreenStream,\n } = store.getState().screenShare\n\n if (screenShareActive) {\n janus.current.stopAllTracks(localScreenStream)\n janus.current.stopAllTracks(remoteScreenStream)\n dispatch.screenShare.update({ active: false })\n plugin.detach()\n }\n break\n\n case 'gateway_down':\n console.warn('THE GATEWAY IS DOWN')\n\n break\n\n case 'info':\n // Check if it's a keyframe request (see: https://github.com/meetecho/janus-gateway/pull/3517)\n if (\n result['type'] === 'application/media_control+xml' &&\n result['content'].includes('<picture_fast_update')\n ) {\n sipcall.send({\n message: { request: 'keyframe', user: true, peer: true },\n })\n }\n break\n\n default:\n if (janus.current.debug) {\n janus.current.debug('Event not handled:', event)\n }\n break\n }\n }\n },\n onlocaltrack: function (track, on) {\n if (janus.current.debug) {\n janus.current.debug('Local track ' + (on ? 'added' : 'removed') + ':', track)\n }\n\n // We use the track ID as name of the element, but it may contain invalid characters\n let trackId = track.id.replace(/[{}]/g, '')\n if (!on) {\n // Track removed, get rid of the stream and the rendering\n let stream = localTracks[trackId]\n if (stream) {\n try {\n let tracks = stream.getTracks()\n for (let i in tracks) {\n let mst = tracks[i]\n if (mst) mst.stop()\n }\n } catch (e: any) {\n if (janus.current.error) {\n janus.current.error('Error removing track:', e)\n }\n }\n }\n if (track.kind === 'video') {\n localVideos--\n }\n delete localTracks[trackId]\n return\n }\n // If we're here, a new track was added\n let stream = localTracks[trackId]\n if (stream) {\n // We've been here already\n return\n }\n if (track.kind === 'audio') {\n // We ignore local audio tracks, they'd generate echo anyway\n\n stream = new MediaStream([track])\n\n // Save the new audio stream to the store\n store.dispatch.webrtc.updateLocalAudioStream(stream)\n } else {\n // New video track: create a stream out of it\n localVideos++\n stream = new MediaStream([track])\n\n // Save the new video stream to the store\n store.dispatch.webrtc.updateLocalVideoStream(stream)\n\n localTracks[trackId] = stream\n if (janus.current.debug) {\n janus.current.debug('Created local stream:', stream)\n }\n const localVideoElement = store.getState().player.localVideo\n\n if (\n janus.current.attachMediaStream &&\n localVideoElement &&\n localVideoElement.current\n ) {\n janus.current.attachMediaStream(localVideoElement.current, stream)\n }\n }\n },\n onremotetrack: function (track, mid, on) {\n if (janus.current.debug) {\n janus.current.debug(\n 'Remote track (mid=' + mid + ') ' + (on ? 'added' : 'removed') + ':',\n track,\n )\n }\n\n // Stop the local audio element ringing\n store.dispatch.player.stopAudioPlayer()\n\n if (!on) {\n // Track removed, get rid of the stream and the rendering\n if (track.kind === 'video') {\n remoteVideos--\n }\n delete remoteTracks[mid]\n\n // Show remote video placeholder\n dispatch.currentCall.updateCurrentCall({\n showRemoteVideoPlaceHolder: true,\n })\n\n return\n }\n\n if (track.kind === 'audio') {\n // New audio track: create a stream out of it, and use a hidden <audio> element\n let stream = new MediaStream([track])\n remoteTracks[mid] = stream\n if (janus.current.debug) {\n janus.current.debug('Created remote audio stream: ' + stream)\n }\n const remoteAudioElement = store.getState().player.remoteAudio\n\n if (\n remoteAudioElement &&\n remoteAudioElement.current &&\n janus.current.attachMediaStream\n ) {\n janus.current.attachMediaStream(remoteAudioElement.current, stream)\n }\n // Save the new audio stream to the store\n store.dispatch.webrtc.updateRemoteAudioStream(stream)\n } else {\n // New video track: create a stream out of it\n remoteVideos++\n let stream = new MediaStream([track])\n\n // Save the new video stream to the store\n store.dispatch.webrtc.updateRemoteVideoStream(stream)\n\n remoteTracks[mid] = stream\n if (janus.current.debug) {\n janus.current.debug('Created remote video stream:' + stream)\n }\n const largeRemoteVideoElement = store.getState().player.largeRemoteVideo\n const smallRemoteVideoElement = store.getState().player.smallRemoteVideo\n\n if (\n janus.current.attachMediaStream &&\n largeRemoteVideoElement &&\n largeRemoteVideoElement.current\n ) {\n janus.current.attachMediaStream(largeRemoteVideoElement.current, stream)\n }\n\n if (\n janus.current.attachMediaStream &&\n smallRemoteVideoElement &&\n smallRemoteVideoElement.current\n ) {\n janus.current.attachMediaStream(smallRemoteVideoElement.current, stream)\n\n // Hide remote video placeholder\n dispatch.currentCall.updateCurrentCall({\n showRemoteVideoPlaceHolder: false,\n })\n }\n }\n },\n oncleanup: function () {\n if (janus.current.log) {\n janus.current.log(' ::: janus Got a cleanup notification :::')\n }\n },\n })\n }\n },\n error: (err: any) => {\n if (janus.current.log) janus.current.log('error', err)\n // Activate webrtc connection alert\n dispatch.alerts.setAlert('webrtc_down')\n },\n destroyed: () => {\n // Set webrtc destroyed status\n dispatch.webrtc.updateWebRTC({\n destroyed: true,\n })\n // Activate webrtc connection alert\n dispatch.alerts.setAlert('webrtc_down')\n },\n })\n // Set janus instance to the store\n dispatch.webrtc.updateWebRTC({\n janusInstance,\n })\n },\n })\n }, [janus.current])\n\n // Check audio and video permissions when default_device is loaded or changed\n useEffect(() => {\n const { default_device } = store.getState().currentUser\n if (default_device !== undefined) {\n checkMediaPermissions()\n }\n }, [store?.getState()?.currentUser?.default_device])\n\n const [isOnline, setIsOnline] = useState(navigator.onLine)\n const [connectionReturned, setConnectionReturned] = useState(false)\n const wasOfflineRef = useRef(false)\n\n useEffect(() => {\n // Event listeners for online/offline status\n const handleOnline = () => setIsOnline(true)\n const handleOffline = () => setIsOnline(false)\n\n window.addEventListener('online', handleOnline)\n window.addEventListener('offline', handleOffline)\n\n return () => {\n window.removeEventListener('online', handleOnline)\n window.removeEventListener('offline', handleOffline)\n }\n }, [])\n\n // Reconnection management\n useEffect(() => {\n if (!isOnline) {\n console.log('Internet connection lost.')\n wasOfflineRef.current = true\n setConnectionReturned(false)\n } else if (wasOfflineRef.current) {\n console.log('Internet connection restored.')\n setConnectionReturned(true)\n wasOfflineRef.current = false\n }\n }, [isOnline])\n\n // Manage webrtc connections and events\n useEffect(() => {\n // Initializes the webrtc registration check interval\n function startWebrtcCheck() {\n const { CHECK_INTERVAL_TIME } = store.getState().webrtc\n if (!janusCheckInterval.current) {\n // Initialize the interval that check the webrtc\n janusCheckInterval.current = setInterval(\n () =>\n webrtcCheck(() => {\n // Do the register as callback of webrtc check\n register({ sipExten, sipSecret, sipHost, sipPort })\n }),\n CHECK_INTERVAL_TIME,\n )\n }\n }\n\n // Start webrtc initialization and handlers\n initWebRTC()\n // Start the check of webrtc activity\n startWebrtcCheck()\n\n return () => {\n // Unregister from janus\n unregister()\n // Stop Janus check interval\n clearInterval(janusCheckInterval.current)\n }\n }, [])\n\n // Manage reload events\n useEffect(() => {\n if (reload || connectionReturned) {\n // Unregister the WebRTC extension\n unregister()\n // Detach sipcall\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n if (sipcall) sipcall.detach()\n // Destroy Janus session\n if (janus.current.destroy) janus.current.destroy()\n // Initialize a new Janus session\n setTimeout(() => {\n initWebRTC()\n // Execute the reloaded callback\n if (reloadedCallback) reloadedCallback()\n }, 10000)\n }\n }, [reload, connectionReturned])\n\n // Manage media devices (audio/video)\n useEffect(() => {\n const getMediaDevices = () => {\n if (navigator && navigator?.mediaDevices && navigator?.mediaDevices?.enumerateDevices) {\n navigator?.mediaDevices\n .enumerateDevices()\n .then((deviceInfos) => {\n dispatch.mediaDevices.updateMediaDevices(deviceInfos)\n })\n .catch((error) => {\n console.error('Error fetching devices:', error)\n })\n } else {\n console.warn('MediaDevices API not supported in this browser or context')\n dispatch.mediaDevices.updateMediaDevices([])\n }\n }\n getMediaDevices()\n\n if (navigator && navigator?.mediaDevices) {\n navigator?.mediaDevices?.addEventListener('devicechange', getMediaDevices)\n\n return () => {\n navigator?.mediaDevices?.removeEventListener('devicechange', getMediaDevices)\n }\n }\n }, [])\n\n useEventListener('phone-island-attach', (data) => {\n initWebRTC()\n eventDispatch('phone-island-attached', {})\n })\n\n /**\n * Event listner for phone-island-call-transfer event\n */\n useEventListener('phone-island-call-transfer', (data) => {\n const transferNumber = data?.to\n dispatch.island.toggleIsOpen(true)\n handleAttendedTransfer(transferNumber)\n eventDispatch('phone-island-call-transfer-opened', {})\n })\n\n async function handleAttendedTransfer(number: string) {\n // Send attended transfer message\n const transferringMessageSent = await attendedTransfer(number)\n if (transferringMessageSent) {\n // Set transferring and disable pause\n dispatch.currentCall.updateCurrentCall({\n transferring: true,\n paused: false,\n })\n // Play the remote audio element\n dispatch.player.playRemoteAudio()\n }\n }\n\n return <>{children}</>\n}\n"],"names":["_a","hostName","sipExten","sipSecret","children","sipHost","sipPort","reload","uaType","reloadedCallback","dispatch","useDispatch","janusCheckInterval","useRef","janus","JanusLib","localTracks","initWebRTC","useCallback","current","init","debug","dependencies","useDefaultDependencies","adapter","callback","janusInstance","server","concat","success","attach","plugin","opaqueId","Date","getTime","pluginHandle","webrtc","updateWebRTC","sipcall","register","log","getPlugin","error","consentDialog","on","webrtcState","iceState","newState","store","getState","mediaState","medium","slowLink","uplink","count","warn","onmessage","msg","jsep","JSON","stringify","undefined","result","event","recording","recorder","view","island","eventDispatch","registered","alerts","removeAlert","type","updateLastActivity","currentCall","checkOutgoingUpdate","outgoingWebRTC","player","audioPlayerPlaying","updateStartAudioPlayer","src","outgoingRingtone","loop","setIslandView","handleRemote","default_device","currentUser","endpoints_1","endpoints","username_1","extensions_1","users","extensions","hasOnlineNethlink","userExtensions","Object","values","filter","ext","username","some","endpointExtension","extension","find","endpoint","id","exten","status","jsepGlobal","setIncoming","checkIncomingUpdatePlay","incoming","incomingWebRTC","updateIncoming","acceptedTimestamp","Math","floor","now","checkAcceptedUpdate","acceptedWebRTC","updateCurrentCall","startTime","toString","stopAudioPlayer","setRecording","isPhysical","hangupCurrentCall","hangup","reset","_b","screenShare","screenShareActive","localScreenStream","remoteScreenStream","stopAllTracks","update","active","detach","console","includes","send","message","request","user","peer","onlocaltrack","track","trackId","replace","stream_1","tracks","getTracks","i","mst","stop","e","kind","stream","MediaStream","updateLocalAudioStream","updateLocalVideoStream","localVideoElement","localVideo","attachMediaStream","onremotetrack","mid","showRemoteVideoPlaceHolder","remoteAudioElement","remoteAudio","updateRemoteAudioStream","updateRemoteVideoStream","largeRemoteVideoElement","largeRemoteVideo","smallRemoteVideoElement","smallRemoteVideo","oncleanup","err","setAlert","destroyed","useEffect","checkMediaPermissions","_c","_d","useState","navigator","onLine","isOnline","setIsOnline","_e","connectionReturned","setConnectionReturned","wasOfflineRef","handleOnline","handleOffline","window","addEventListener","removeEventListener","CHECK_INTERVAL_TIME","setInterval","webrtcCheck","unregister","clearInterval","destroy","setTimeout","getMediaDevices","mediaDevices","enumerateDevices","then","deviceInfos","updateMediaDevices","catch","useEventListener","data","transferNumber","to","toggleIsOpen","number","attendedTransfer","sent","transferring","paused","playRemoteAudio","handleAttendedTransfer","React","createElement","Fragment"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"WebRTC.js","sources":["../../src/components/WebRTC.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, useCallback, useState } from 'react'\nimport { useDispatch } from 'react-redux'\nimport { Dispatch } from '../store'\nimport adapter from 'webrtc-adapter'\nimport JanusLib from '../lib/webrtc/janus.js'\nimport type { JanusTypes } from '../types'\nimport { register, unregister, handleRemote } from '../lib/webrtc/messages'\nimport { store } from '../store'\nimport { checkMediaPermissions } from '../lib/devices/devices'\nimport { attendedTransfer, hangupCurrentCall } from '../lib/phone/call'\nimport { webrtcCheck } from '../lib/webrtc/connection'\nimport outgoingRingtone from '../static/outgoing_ringtone'\nimport { eventDispatch, useEventListener, getJSONItem, setJSONItem } from '../utils'\nimport { isPhysical } from '../lib/user/default_device'\n\ninterface WebRTCProps {\n children: ReactNode\n sipExten: string\n sipSecret: string\n hostName: string\n sipHost: string\n sipPort: string\n reload: boolean\n uaType: string\n reloadedCallback?: () => void\n}\n\nexport const WebRTC: FC<WebRTCProps> = ({\n hostName,\n sipExten,\n sipSecret,\n children,\n sipHost,\n sipPort,\n reload,\n uaType,\n reloadedCallback,\n}) => {\n // Initialize store dispatch\n const dispatch = useDispatch<Dispatch>()\n\n // Initialize janus check interval id\n const janusCheckInterval = useRef<any>(null)\n\n // Initialize Janus from Janus library\n const janus = useRef<JanusTypes>(JanusLib)\n\n let localTracks = {}\n let localVideos = 0\n let remoteTracks = {}\n let remoteVideos = 0\n\n // Initializes the webrtc connection and handlers\n const initWebRTC = useCallback(() => {\n janus.current.init({\n debug: 'all',\n dependencies: janus.current.useDefaultDependencies({\n adapter,\n }),\n callback: function () {\n const janusInstance = new janus.current({\n server: `https://${hostName}/janus`,\n success: () => {\n if (janusInstance.attach) {\n // Use Janus Sip Plugin\n janusInstance.attach({\n plugin: 'janus.plugin.sip',\n opaqueId: 'sebastian' + '_' + new Date().getTime(),\n success: function (pluginHandle) {\n // Set sipcall to the store\n if (pluginHandle) {\n dispatch.webrtc.updateWebRTC({\n sipcall: pluginHandle,\n })\n // Register the extension to the server\n register({ sipExten, sipSecret, sipHost, sipPort })\n if (pluginHandle) {\n if (janus.current.log)\n janus.current.log(\n 'SIP plugin attached! (' + pluginHandle.getPlugin() + ', id = ' + ')',\n )\n }\n }\n },\n error: function (error) {\n if (janus.current.error) {\n janus.current.error(' -- Error attaching plugin...')\n janus.current.error(error)\n }\n // reject()\n },\n consentDialog: function (on) {\n if (janus.current.log) janus.current.log(`janus consentDialog (on: ${on})`)\n },\n webrtcState: function (on) {\n if (janus.current.log)\n janus.current.log(\n 'Janus says our WebRTC PeerConnection is ' + (on ? 'up' : 'down') + ' now',\n )\n },\n iceState: function (newState) {\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n\n if (sipcall) {\n if (janus.current.log)\n janus.current.log(\n `ICE state of PeerConnection of handle has changed to \"${newState}\"`,\n )\n }\n },\n mediaState: function (medium, on) {\n if (janus.current.log)\n janus.current.log(\n 'Janus ' + (on ? 'started' : 'stopped') + ' receiving our ' + medium,\n )\n },\n slowLink: function (uplink, count) {\n if (uplink) {\n if (janus.current.warn)\n janus.current.warn(`SLOW link: several missing packets from janus (${count})`)\n } else {\n if (janus.current.warn)\n janus.current.warn(\n `SLOW link: janus is not receiving all your packets (${count})`,\n )\n }\n },\n onmessage: function (msg, jsep) {\n // Get webrtc state\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n\n if (janus.current.debug) {\n janus.current.debug(' ::: Got a message :::')\n janus.current.debug(JSON.stringify(msg))\n }\n\n // Handle errors in message\n var error = msg['error']\n if (error != null && error != undefined) {\n if (!store.getState().webrtc.registered) {\n if (janus.current.log) janus.current.log('User is not registered')\n } else {\n // Reset status\n sipcall && sipcall.hangup()\n\n // Stop the local audio element ringing\n store.dispatch.player.stopAudioPlayer()\n }\n return\n }\n // Manage events\n var result = msg['result']\n if (\n result !== null &&\n result !== undefined &&\n result['event'] !== undefined &&\n result['event'] !== null\n ) {\n // Get event data\n var event = result['event']\n\n // Get the recording state\n const { recording } = store.getState().recorder\n const { view } = store.getState().island\n\n // Manage different types of events\n switch (event) {\n case 'registration_failed':\n if (janus.current.error)\n janus.current.error(\n 'Registration failed: ' + result['code'] + ' ' + result['reason'],\n )\n break\n\n case 'unregistered':\n if (janus.current.log)\n janus.current.log(\n 'Successfully un-registered as ' + result['username'] + '!',\n )\n eventDispatch('phone-island-webrtc-unregistered', {})\n break\n\n case 'registered':\n if (janus.current.log)\n janus.current.log(\n 'Successfully registered as ' + result['username'] + '!',\n )\n eventDispatch('phone-island-webrtc-registered', {})\n if (!store.getState().webrtc.registered) {\n store.dispatch.webrtc.updateWebRTC({\n registered: true,\n })\n }\n // Remove WebRTC connections alert if any\n dispatch.alerts.removeAlert('webrtc_down')\n eventDispatch('phone-island-alert-removed', {\n type: 'webrtc_down',\n })\n // Update webrtc lastActivity time\n dispatch.webrtc.updateLastActivity(new Date().getTime())\n break\n\n case 'registering':\n if (janus.current.log) {\n janus.current.log('janus registering')\n }\n break\n\n // This event arrive on outgoing call start\n case 'calling':\n // Number and display name are updated inside socket\n dispatch.currentCall.checkOutgoingUpdate({\n outgoingWebRTC: true,\n })\n\n // Update webrtc last activity time\n dispatch.webrtc.updateLastActivity(new Date().getTime())\n break\n\n // After an outgoing call start on 180 code, it means\n // ...that the local outgoing ringtone must be player\n case 'ringing':\n const { audioPlayerPlaying } = store.getState().player\n\n // Check if the local audio is already playing and start playing\n if (!audioPlayerPlaying) {\n // Update audio player and start playing\n dispatch.player.updateStartAudioPlayer({\n src: outgoingRingtone,\n loop: true,\n })\n }\n // Update webrtc lastActivity time\n dispatch.webrtc.updateLastActivity(new Date().getTime())\n if (view !== 'call') {\n dispatch.island.setIslandView('call')\n }\n break\n\n // After an outgoing call start on 183 code, it means\n // ...that the outgoing ringtone arrives from the stream\n // ...playing the local outgoing ringtone isn't needed\n case 'progress':\n if (janus.current.log) {\n janus.current.log(\n \"There's early media from \" +\n result['username'] +\n ', wairing for the call!',\n )\n }\n // Set the remote description to janus lib\n if (jsep) {\n handleRemote(jsep)\n }\n // Update webrtc lastActivity time\n dispatch.webrtc.updateLastActivity(new Date().getTime())\n break\n\n case 'incomingcall':\n const { default_device } = store.getState().currentUser\n const { endpoints, username } = store.getState().currentUser\n const { extensions } = store.getState().users\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 (\n endpointExtension?.type === 'nethlink' && ext?.status !== 'offline'\n )\n })\n }\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 // Update webrtc state\n dispatch.webrtc.updateWebRTC({ jsepGlobal: jsep })\n // Check if is recording an audio through call\n // ...recording an audio is a request made by the user\n // ...it must be managed differently than an incoming call\n if (recording) {\n // Update the recorder state\n dispatch.recorder.setIncoming(true)\n } else {\n // Manage the incoming message as a webrtc call\n // Update incoming webrtc state, number and display name\n // ...are updated inside socket\n dispatch.currentCall.checkIncomingUpdatePlay({\n incoming: true,\n incomingWebRTC: true,\n })\n\n if (janus.current.log) {\n dispatch.currentCall.updateIncoming(true)\n janus.current.log('Incoming call from ' + result['username'] + '!')\n }\n }\n\n // Update the webrtc last activity time\n dispatch.webrtc.updateLastActivity(new Date().getTime())\n }\n\n break\n\n case 'accepted':\n const acceptedTimestamp = Math.floor(Date.now() / 1000)\n if (janus.current.log) {\n janus.current.log(result['username'] + ' accepted the call!')\n }\n // Set the remote description to janus lib\n if (jsep) {\n handleRemote(jsep)\n }\n // Set current call accepted\n dispatch.currentCall.checkAcceptedUpdate({\n acceptedWebRTC: true,\n })\n\n // Set incoming value to false and set start time\n dispatch.currentCall.updateCurrentCall({\n incoming: false,\n incomingWebRTC: false,\n startTime: acceptedTimestamp?.toString(),\n })\n\n // Stop the local audio element ringing\n store.dispatch.player.stopAudioPlayer()\n\n // Update webrtc lastActivity time\n dispatch.webrtc.updateLastActivity(new Date().getTime())\n break\n\n case 'hangup':\n // Manage hangup message during recording\n if (recording) {\n dispatch.recorder.setRecording(false)\n }\n if (!isPhysical() && uaType !== 'mobile') {\n hangupCurrentCall()\n sipcall.hangup()\n\n // Stop the local audio element ringing\n store.dispatch.player.stopAudioPlayer()\n\n // Check the janus doc before enable the following\n // if (\n // result['code'] === 486 &&\n // result['event'] === 'hangup' &&\n // result['reason'] === 'Busy Here'\n // ) {\n // dispatch.player.updateAudioSource({\n // src: busyRingtone,\n // })\n // dispatch.player.playAudio()\n // }\n // Reset current call info\n store.dispatch.currentCall.reset()\n if (janus.current.log)\n janus.current.log(\n 'Call hung up (' + result['code'] + ' ' + result['reason'] + ')!',\n )\n // Update webrtc lastActivity time\n dispatch.webrtc.updateLastActivity(new Date().getTime())\n // stopScreenSharingI()\n }\n\n // Stop the local audio element ringing\n store.dispatch.player.stopAudioPlayer()\n\n // Stop screen sharing if active\n const {\n active: screenShareActive,\n plugin,\n localScreenStream,\n remoteScreenStream,\n } = store.getState().screenShare\n\n if (screenShareActive) {\n janus.current.stopAllTracks(localScreenStream)\n janus.current.stopAllTracks(remoteScreenStream)\n dispatch.screenShare.update({ active: false })\n plugin.detach()\n }\n break\n\n case 'gateway_down':\n console.warn('THE GATEWAY IS DOWN')\n\n break\n\n case 'info':\n // Check if it's a keyframe request (see: https://github.com/meetecho/janus-gateway/pull/3517)\n if (\n result['type'] === 'application/media_control+xml' &&\n result['content'].includes('<picture_fast_update')\n ) {\n sipcall.send({\n message: { request: 'keyframe', user: true, peer: true },\n })\n }\n break\n\n default:\n if (janus.current.debug) {\n janus.current.debug('Event not handled:', event)\n }\n break\n }\n }\n },\n onlocaltrack: function (track, on) {\n if (janus.current.debug) {\n janus.current.debug('Local track ' + (on ? 'added' : 'removed') + ':', track)\n }\n\n // We use the track ID as name of the element, but it may contain invalid characters\n let trackId = track.id.replace(/[{}]/g, '')\n if (!on) {\n // Track removed, get rid of the stream and the rendering\n let stream = localTracks[trackId]\n if (stream) {\n try {\n let tracks = stream.getTracks()\n for (let i in tracks) {\n let mst = tracks[i]\n if (mst) mst.stop()\n }\n } catch (e: any) {\n if (janus.current.error) {\n janus.current.error('Error removing track:', e)\n }\n }\n }\n if (track.kind === 'video') {\n localVideos--\n }\n delete localTracks[trackId]\n return\n }\n // If we're here, a new track was added\n let stream = localTracks[trackId]\n if (stream) {\n // We've been here already\n return\n }\n if (track.kind === 'audio') {\n // We ignore local audio tracks, they'd generate echo anyway\n\n stream = new MediaStream([track])\n\n // Save the new audio stream to the store\n store.dispatch.webrtc.updateLocalAudioStream(stream)\n } else {\n // New video track: create a stream out of it\n localVideos++\n stream = new MediaStream([track])\n\n // Save the new video stream to the store\n store.dispatch.webrtc.updateLocalVideoStream(stream)\n\n localTracks[trackId] = stream\n if (janus.current.debug) {\n janus.current.debug('Created local stream:', stream)\n }\n const localVideoElement = store.getState().player.localVideo\n\n if (\n janus.current.attachMediaStream &&\n localVideoElement &&\n localVideoElement.current\n ) {\n janus.current.attachMediaStream(localVideoElement.current, stream)\n }\n }\n },\n onremotetrack: function (track, mid, on) {\n if (janus.current.debug) {\n janus.current.debug(\n 'Remote track (mid=' + mid + ') ' + (on ? 'added' : 'removed') + ':',\n track,\n )\n }\n\n // Stop the local audio element ringing\n store.dispatch.player.stopAudioPlayer()\n\n if (!on) {\n // Track removed, get rid of the stream and the rendering\n if (track.kind === 'video') {\n remoteVideos--\n }\n delete remoteTracks[mid]\n\n // Show remote video placeholder\n dispatch.currentCall.updateCurrentCall({\n showRemoteVideoPlaceHolder: true,\n })\n\n return\n }\n\n if (track.kind === 'audio') {\n // New audio track: create a stream out of it, and use a hidden <audio> element\n let stream = new MediaStream([track])\n remoteTracks[mid] = stream\n if (janus.current.debug) {\n janus.current.debug('Created remote audio stream: ' + stream)\n }\n const remoteAudioElement = store.getState().player.remoteAudio\n\n if (\n remoteAudioElement &&\n remoteAudioElement.current &&\n janus.current.attachMediaStream\n ) {\n janus.current.attachMediaStream(remoteAudioElement.current, stream)\n\n // Apply saved audio output device if available\n const defaultAudioOutputDevice: any = getJSONItem('phone-island-audio-output-device')\n\n if (defaultAudioOutputDevice?.deviceId) {\n const applySavedDevice = async () => {\n let targetDeviceId = defaultAudioOutputDevice.deviceId\n\n // Check if the saved device is still available\n if (targetDeviceId && targetDeviceId !== 'default') {\n try {\n const devices = await navigator.mediaDevices.enumerateDevices()\n const audioOutputDevices = devices.filter(device => device.kind === 'audiooutput')\n const deviceExists = audioOutputDevices.some(device => device.deviceId === targetDeviceId)\n\n if (!deviceExists) {\n console.warn(`Saved audio device ${targetDeviceId} no longer available, using default device`)\n targetDeviceId = 'default'\n // Update localStorage with the fallback\n setJSONItem('phone-island-audio-output-device', { deviceId: 'default' })\n }\n } catch (err) {\n console.warn('Error checking device availability, using default:', err)\n targetDeviceId = 'default'\n }\n }\n\n // Apply the device\n try {\n await remoteAudioElement.current.setSinkId(targetDeviceId)\n console.info('Audio output device applied successfully to new stream:', targetDeviceId)\n } catch (err) {\n console.warn('Failed to apply audio output device to new stream:', err)\n // Final fallback to default if not already using it\n if (targetDeviceId !== 'default') {\n try {\n await remoteAudioElement.current.setSinkId('default')\n setJSONItem('phone-island-audio-output-device', { deviceId: 'default' })\n console.info('Fallback to default device successful')\n } catch (defaultErr) {\n console.error('Even default device failed:', defaultErr)\n }\n }\n }\n }\n\n applySavedDevice()\n }\n }\n // Save the new audio stream to the store\n store.dispatch.webrtc.updateRemoteAudioStream(stream)\n } else {\n // New video track: create a stream out of it\n remoteVideos++\n let stream = new MediaStream([track])\n\n // Save the new video stream to the store\n store.dispatch.webrtc.updateRemoteVideoStream(stream)\n\n remoteTracks[mid] = stream\n if (janus.current.debug) {\n janus.current.debug('Created remote video stream:' + stream)\n }\n const largeRemoteVideoElement = store.getState().player.largeRemoteVideo\n const smallRemoteVideoElement = store.getState().player.smallRemoteVideo\n\n if (\n janus.current.attachMediaStream &&\n largeRemoteVideoElement &&\n largeRemoteVideoElement.current\n ) {\n janus.current.attachMediaStream(largeRemoteVideoElement.current, stream)\n }\n\n if (\n janus.current.attachMediaStream &&\n smallRemoteVideoElement &&\n smallRemoteVideoElement.current\n ) {\n janus.current.attachMediaStream(smallRemoteVideoElement.current, stream)\n\n // Hide remote video placeholder\n dispatch.currentCall.updateCurrentCall({\n showRemoteVideoPlaceHolder: false,\n })\n }\n }\n },\n oncleanup: function () {\n if (janus.current.log) {\n janus.current.log(' ::: janus Got a cleanup notification :::')\n }\n },\n })\n }\n },\n error: (err: any) => {\n if (janus.current.log) janus.current.log('error', err)\n // Activate webrtc connection alert\n dispatch.alerts.setAlert('webrtc_down')\n },\n destroyed: () => {\n // Set webrtc destroyed status\n dispatch.webrtc.updateWebRTC({\n destroyed: true,\n })\n // Activate webrtc connection alert\n dispatch.alerts.setAlert('webrtc_down')\n },\n })\n // Set janus instance to the store\n dispatch.webrtc.updateWebRTC({\n janusInstance,\n })\n },\n })\n }, [janus.current])\n\n // Check audio and video permissions when default_device is loaded or changed\n useEffect(() => {\n const { default_device } = store.getState().currentUser\n if (default_device !== undefined) {\n checkMediaPermissions()\n }\n }, [store?.getState()?.currentUser?.default_device])\n\n const [isOnline, setIsOnline] = useState(navigator.onLine)\n const [connectionReturned, setConnectionReturned] = useState(false)\n const wasOfflineRef = useRef(false)\n\n useEffect(() => {\n // Event listeners for online/offline status\n const handleOnline = () => setIsOnline(true)\n const handleOffline = () => setIsOnline(false)\n\n window.addEventListener('online', handleOnline)\n window.addEventListener('offline', handleOffline)\n\n return () => {\n window.removeEventListener('online', handleOnline)\n window.removeEventListener('offline', handleOffline)\n }\n }, [])\n\n // Reconnection management\n useEffect(() => {\n if (!isOnline) {\n console.log('Internet connection lost.')\n wasOfflineRef.current = true\n setConnectionReturned(false)\n } else if (wasOfflineRef.current) {\n console.log('Internet connection restored.')\n setConnectionReturned(true)\n wasOfflineRef.current = false\n }\n }, [isOnline])\n\n // Manage webrtc connections and events\n useEffect(() => {\n // Initializes the webrtc registration check interval\n function startWebrtcCheck() {\n const { CHECK_INTERVAL_TIME } = store.getState().webrtc\n if (!janusCheckInterval.current) {\n // Initialize the interval that check the webrtc\n janusCheckInterval.current = setInterval(\n () =>\n webrtcCheck(() => {\n // Do the register as callback of webrtc check\n register({ sipExten, sipSecret, sipHost, sipPort })\n }),\n CHECK_INTERVAL_TIME,\n )\n }\n }\n\n // Start webrtc initialization and handlers\n initWebRTC()\n // Start the check of webrtc activity\n startWebrtcCheck()\n\n return () => {\n // Unregister from janus\n unregister()\n // Stop Janus check interval\n clearInterval(janusCheckInterval.current)\n }\n }, [])\n\n // Manage reload events\n useEffect(() => {\n if (reload || connectionReturned) {\n // Unregister the WebRTC extension\n unregister()\n // Detach sipcall\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n if (sipcall) sipcall.detach()\n // Destroy Janus session\n if (janus.current.destroy) janus.current.destroy()\n // Initialize a new Janus session\n setTimeout(() => {\n initWebRTC()\n // Execute the reloaded callback\n if (reloadedCallback) reloadedCallback()\n }, 10000)\n }\n }, [reload, connectionReturned])\n\n // Manage media devices (audio/video)\n useEffect(() => {\n const getMediaDevices = () => {\n if (navigator && navigator?.mediaDevices && navigator?.mediaDevices?.enumerateDevices) {\n navigator?.mediaDevices\n .enumerateDevices()\n .then((deviceInfos) => {\n dispatch.mediaDevices.updateMediaDevices(deviceInfos)\n })\n .catch((error) => {\n console.error('Error fetching devices:', error)\n })\n } else {\n console.warn('MediaDevices API not supported in this browser or context')\n dispatch.mediaDevices.updateMediaDevices([])\n }\n }\n getMediaDevices()\n\n if (navigator && navigator?.mediaDevices) {\n navigator?.mediaDevices?.addEventListener('devicechange', getMediaDevices)\n\n return () => {\n navigator?.mediaDevices?.removeEventListener('devicechange', getMediaDevices)\n }\n }\n }, [])\n\n useEventListener('phone-island-attach', (data) => {\n initWebRTC()\n eventDispatch('phone-island-attached', {})\n })\n\n /**\n * Event listner for phone-island-call-transfer event\n */\n useEventListener('phone-island-call-transfer', (data) => {\n const transferNumber = data?.to\n dispatch.island.toggleIsOpen(true)\n handleAttendedTransfer(transferNumber)\n eventDispatch('phone-island-call-transfer-opened', {})\n })\n\n async function handleAttendedTransfer(number: string) {\n // Send attended transfer message\n const transferringMessageSent = await attendedTransfer(number)\n if (transferringMessageSent) {\n // Set transferring and disable pause\n dispatch.currentCall.updateCurrentCall({\n transferring: true,\n paused: false,\n })\n // Play the remote audio element\n dispatch.player.playRemoteAudio()\n }\n }\n\n return <>{children}</>\n}\n"],"names":["_a","hostName","sipExten","sipSecret","children","sipHost","sipPort","reload","uaType","reloadedCallback","dispatch","useDispatch","janusCheckInterval","useRef","janus","JanusLib","localTracks","initWebRTC","useCallback","current","init","debug","dependencies","useDefaultDependencies","adapter","callback","janusInstance","server","concat","success","attach","plugin","opaqueId","Date","getTime","pluginHandle","webrtc","updateWebRTC","sipcall","register","log","getPlugin","error","consentDialog","on","webrtcState","iceState","newState","store","getState","mediaState","medium","slowLink","uplink","count","warn","onmessage","msg","jsep","JSON","stringify","undefined","result","event","recording","recorder","view","island","eventDispatch","registered","alerts","removeAlert","type","updateLastActivity","currentCall","checkOutgoingUpdate","outgoingWebRTC","player","audioPlayerPlaying","updateStartAudioPlayer","src","outgoingRingtone","loop","setIslandView","handleRemote","default_device","currentUser","endpoints_1","endpoints","username_1","extensions_1","users","extensions","hasOnlineNethlink","userExtensions","Object","values","filter","ext","username","some","endpointExtension","extension","find","endpoint","id","exten","status","jsepGlobal","setIncoming","checkIncomingUpdatePlay","incoming","incomingWebRTC","updateIncoming","acceptedTimestamp","Math","floor","now","checkAcceptedUpdate","acceptedWebRTC","updateCurrentCall","startTime","toString","stopAudioPlayer","setRecording","isPhysical","hangupCurrentCall","hangup","reset","_b","screenShare","screenShareActive","localScreenStream","remoteScreenStream","stopAllTracks","update","active","detach","console","includes","send","message","request","user","peer","onlocaltrack","track","trackId","replace","stream_1","tracks","getTracks","i","mst","stop","e","kind","stream","MediaStream","updateLocalAudioStream","updateLocalVideoStream","localVideoElement","localVideo","attachMediaStream","onremotetrack","mid","_this","this","showRemoteVideoPlaceHolder","remoteAudioElement_1","remoteAudio","defaultAudioOutputDevice_1","getJSONItem","deviceId","__awaiter","targetDeviceId","navigator","mediaDevices","enumerateDevices","devices","sent","device","setJSONItem","err_1","setSinkId","info","err_2","defaultErr_1","updateRemoteAudioStream","updateRemoteVideoStream","largeRemoteVideoElement","largeRemoteVideo","smallRemoteVideoElement","smallRemoteVideo","oncleanup","err","setAlert","destroyed","useEffect","checkMediaPermissions","_c","_d","useState","onLine","isOnline","setIsOnline","_e","connectionReturned","setConnectionReturned","wasOfflineRef","handleOnline","handleOffline","window","addEventListener","removeEventListener","CHECK_INTERVAL_TIME","setInterval","webrtcCheck","unregister","clearInterval","destroy","setTimeout","getMediaDevices","then","deviceInfos","updateMediaDevices","catch","useEventListener","data","transferNumber","to","toggleIsOpen","number","attendedTransfer","transferring","paused","playRemoteAudio","handleAttendedTransfer","React","createElement","Fragment"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),require("../../node_modules/mic-check/lib/index.js");var e=require("../webrtc/janus.js"),i=require("../../store/index.js"),r=require("../user/default_device.js");require("react");var t=require("../../utils/genericFunctions/localStorage.js"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),require("../../node_modules/mic-check/lib/index.js");var e=require("../webrtc/janus.js"),i=require("../../store/index.js"),r=require("../user/default_device.js");require("react");var t=require("../../utils/genericFunctions/localStorage.js"),n=require("../../_virtual/index8.js"),o=e.default;exports.checkMediaPermissions=function(){if(r.isPhysical())return i.store.dispatch.alerts.removeAlert("browser_permissions"),i.store.dispatch.alerts.removeAlert("user_permissions"),i.store.dispatch.alerts.removeAlert("busy_camera"),void i.store.dispatch.alerts.removeAlert("unknown_media_permissions");n.__exports.requestMediaPermissions({audio:!0}).then((function(){})).catch((function(e){var r,t,s=e.type,d=null!==(t=((r={})[n.__exports.MediaPermissionsErrorType.SystemPermissionDenied]={alert:"browser_permissions",message:"WebRTC: browser does not have permission to access camera or microphone"},r[n.__exports.MediaPermissionsErrorType.UserPermissionDenied]={alert:"user_permissions",message:"WebRTC: user didn't allow app to access camera or microphone"},r)[s])&&void 0!==t?t:{alert:"unknown_media_permissions",message:"WebRTC: can't access audio or camera on this device. unknown error"};i.store.dispatch.alerts.setAlert(d.alert),o.error&&o.error(d.message)}))},exports.checkWebCamPermission=function(){return new Promise((function(e){n.__exports.requestMediaPermissions({video:!0}).then((function(){e(!0)})).catch((function(i){console.error("Error requesting webcam permission:",i),e(!1)}))}))},exports.getCurrentAudioInputDeviceId=function(){var e=t.getJSONItem("phone-island-audio-input-device").deviceId||null,r=i.store.select.mediaDevices.audioInputDevices(i.store.getState());if(r.find((function(i){return i.deviceId===e})))return e;var n=r.find((function(e){return"default"===e.deviceId||""===e.deviceId}))||r[0],o=n?n.deviceId:"default";return null!==e&&o!==e&&(console.warn("Audio input device ".concat(e," no longer available, falling back to default device")),t.setJSONItem("phone-island-audio-input-device",{deviceId:o})),o},exports.getCurrentAudioOutputDeviceId=function(){var e=t.getJSONItem("phone-island-audio-output-device").deviceId||null,r=i.store.select.mediaDevices.audioOutputDevices(i.store.getState());if(r.find((function(i){return i.deviceId===e})))return e;var n=r.find((function(e){return"default"===e.deviceId||""===e.deviceId}))||r[0],o=n?n.deviceId:"default";return null!==e&&o!==e&&(console.warn("Audio output device ".concat(e," no longer available, falling back to default device")),t.setJSONItem("phone-island-audio-output-device",{deviceId:o})),o},exports.getCurrentVideoInputDeviceId=function(){var e=t.getJSONItem("phone-island-video-input-device").deviceId||null,r=i.store.select.mediaDevices.videoInputDevices(i.store.getState());if(r.find((function(i){return i.deviceId===e})))return e;var n=r.find((function(e){return"default"===e.deviceId||""===e.deviceId}))||r[0],o=n?n.deviceId:"default";return null!==e&&o!==e&&(console.warn("Video input device ".concat(e," no longer available, falling back to default device")),t.setJSONItem("phone-island-video-input-device",{deviceId:o})),o},exports.getSupportedDevices=function(e){var i,r,t=!1,n=!1,s=!1,d=!1;i=function(){var i={audio:t,audioCap:s,video:n,videoCap:d};o.log&&o.log("supportedDevices=",i),e()},r=[],navigator.mediaDevices.enumerateDevices().then((function(e){e.forEach((function(e){var i=!1;r.forEach((function(r){r.deviceId===e.deviceId&&r.kind===e.kind&&(i=!0)})),i||("videoinput"!==e.kind||d||(d=!0),"audioinput"!==e.kind||s||(s=!0),"audioinput"===e.kind&&(t=!0),e.kind,"videoinput"===e.kind&&(n=!0),r.push(e))})),i&&i()}))};
|
|
2
2
|
//# sourceMappingURL=devices.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"devices.js","sources":["../../../src/lib/devices/devices.ts"],"sourcesContent":["// Copyright (C) 2024 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport {\n MediaPermissionsError,\n MediaPermissionsErrorType,\n requestMediaPermissions,\n} from 'mic-check'\nimport JanusLib from '../webrtc/janus'\nimport { JanusTypes } from '../../types'\nimport { store } from '../../store'\nimport { isPhysical } from '../user/default_device'\nimport { getJSONItem } from '../../utils'\nimport { eventDispatch} from '../../utils/genericFunctions/eventDispatch'\n\nconst Janus: JanusTypes = JanusLib\n\nexport const getSupportedDevices = function (origCallback: () => void) {\n let hasMicrophone = false\n let hasSpeakers = false\n let hasWebcam = false\n let isMicrophoneAlreadyCaptured = false\n let isWebcamAlreadyCaptured = false\n\n function checkDeviceSupport(callback: () => void) {\n const mediaDevices: MediaDeviceInfo[] = []\n\n navigator.mediaDevices.enumerateDevices().then((devices: MediaDeviceInfo[]) => {\n devices.forEach(function (device: MediaDeviceInfo) {\n let skip = false\n\n mediaDevices.forEach(function (d: MediaDeviceInfo) {\n if (d.deviceId === device.deviceId && d.kind === device.kind) {\n skip = true\n }\n })\n\n if (skip) {\n return\n }\n\n if (device.kind === 'videoinput' && !isWebcamAlreadyCaptured) {\n isWebcamAlreadyCaptured = true\n }\n if (device.kind === 'audioinput' && !isMicrophoneAlreadyCaptured) {\n isMicrophoneAlreadyCaptured = true\n }\n\n if (device.kind === 'audioinput') {\n hasMicrophone = true\n }\n\n if (device.kind === 'audiooutput') {\n hasSpeakers = true\n }\n\n if (device.kind === 'videoinput') {\n hasWebcam = true\n }\n\n mediaDevices.push(device)\n })\n\n if (callback) {\n callback()\n }\n })\n }\n\n // check for microphone/camera support!\n checkDeviceSupport(function () {\n const supportedDevices: any = {\n audio: hasMicrophone,\n audioCap: isMicrophoneAlreadyCaptured,\n video: hasWebcam,\n videoCap: isWebcamAlreadyCaptured,\n }\n\n Janus.log && Janus.log('supportedDevices=', supportedDevices)\n origCallback()\n })\n}\n\nexport const checkMediaPermissions = function () {\n //Remove all media alerts if default_device is physical\n if (isPhysical()) {\n store.dispatch.alerts.removeAlert('browser_permissions')\n store.dispatch.alerts.removeAlert('user_permissions')\n store.dispatch.alerts.removeAlert('busy_camera')\n store.dispatch.alerts.removeAlert('unknown_media_permissions')\n return\n }\n\n requestMediaPermissions({ audio: true })\n .then(() => {\n // Can successfully access camera and microphone streams\n // Save permissions state on rematch to get access globally on the app\n })\n .catch((err: any) => {\n const { type } = err\n\n // Define error mappings for different types of media permission errors\n const errorMap: any = {\n [MediaPermissionsErrorType.SystemPermissionDenied]: {\n alert: 'browser_permissions',\n message: 'WebRTC: browser does not have permission to access camera or microphone',\n },\n [MediaPermissionsErrorType.UserPermissionDenied]: {\n alert: 'user_permissions',\n message: \"WebRTC: user didn't allow app to access camera or microphone\",\n },\n }\n\n // Get error details from map or use default error\n const error = errorMap[type] ?? {\n alert: 'unknown_media_permissions',\n message: \"WebRTC: can't access audio or camera on this device. unknown error\",\n }\n\n // Display alert only for non-physical devices\n store.dispatch.alerts.setAlert(error.alert)\n\n // Log error message if Janus logger is available\n if (Janus.error) {\n Janus.error(error.message)\n }\n })\n}\n\nexport const checkWebCamPermission = function (): Promise<boolean> {\n return new Promise((resolve) => {\n requestMediaPermissions({ video: true })\n .then(() => {\n resolve(true)\n })\n .catch((err: any) => {\n console.error('Error requesting webcam permission:', err)\n resolve(false)\n })\n })\n}\n\nexport const getCurrentVideoInputDeviceId = function () {\n const currentDeviceId = getJSONItem('phone-island-video-input-device').deviceId || null\n const videoInputDevices = store.select.mediaDevices.videoInputDevices(store.getState())\n\n // Check if the current device is still available\n const deviceFound = videoInputDevices.find((device) => device.deviceId === currentDeviceId)\n\n if (deviceFound) {\n return currentDeviceId\n } else {\n return null\n }\n}\n\nexport const getCurrentAudioInputDeviceId = function () {\n const currentDeviceId = getJSONItem('phone-island-audio-input-device').deviceId || null\n const audioInputDevices = store.select.mediaDevices.audioInputDevices(store.getState())\n\n // Check if the current device is still available\n const deviceFound = audioInputDevices.find((device) => device.deviceId === currentDeviceId)\n\n if (deviceFound) {\n return currentDeviceId\n } else {\n return null\n }\n}\n\nexport const getCurrentAudioOutputDeviceId = function () {\n const currentDeviceId = getJSONItem('phone-island-audio-output-device').deviceId || null\n const audioOutputDevices = store.select.mediaDevices.audioOutputDevices(store.getState())\n\n // Check if the current device is still available\n const deviceFound = audioOutputDevices.find((device) => device.deviceId === currentDeviceId)\n\n if (deviceFound) {\n return currentDeviceId\n } else {\n return null\n }\n}\n"],"names":["Janus","JanusLib","isPhysical","store","dispatch","alerts","removeAlert","requestMediaPermissions","audio","then","catch","err","type","error","_b","_a","MediaPermissionsErrorType","SystemPermissionDenied","alert","message","UserPermissionDenied","setAlert","Promise","resolve","video","console","currentDeviceId","getJSONItem","deviceId","select","mediaDevices","audioInputDevices","getState","find","device","audioOutputDevices","videoInputDevices","origCallback","callback","hasMicrophone","hasWebcam","isMicrophoneAlreadyCaptured","isWebcamAlreadyCaptured","supportedDevices","audioCap","videoCap","log","navigator","enumerateDevices","devices","forEach","skip","d","kind","push"],"mappings":"2VAeMA,EAAoBC,EAAAA,sCAoEW,WAEnC,GAAIC,EAAUA,aAKZ,OAJAC,EAAAA,MAAMC,SAASC,OAAOC,YAAY,uBAClCH,EAAAA,MAAMC,SAASC,OAAOC,YAAY,oBAClCH,EAAAA,MAAMC,SAASC,OAAOC,YAAY,oBAClCH,EAAAA,MAAMC,SAASC,OAAOC,YAAY,6BAIpCC,oCAAwB,CAAEC,OAAO,IAC9BC,MAAK,WAGN,IACCC,OAAM,SAACC,WACEC,EAASD,EAAGC,KAedC,EAA0B,QAAlBC,IAZAC,EAAA,CAAA,GACXC,EAAAA,UAAAA,0BAA0BC,wBAAyB,CAClDC,MAAO,sBACPC,QAAS,2EAEXJ,EAACC,EAAAA,UAAAA,0BAA0BI,sBAAuB,CAChDF,MAAO,mBACPC,QAAS,mEAKUP,UAAS,IAAAE,EAAAA,EAAA,CAC9BI,MAAO,4BACPC,QAAS,sEAIXhB,EAAKA,MAACC,SAASC,OAAOgB,SAASR,EAAMK,OAGjClB,EAAMa,OACRb,EAAMa,MAAMA,EAAMM,QAEtB,GACJ,gCAEqC,WACnC,OAAO,IAAIG,SAAQ,SAACC,GAClBhB,oCAAwB,CAAEiB,OAAO,IAC9Bf,MAAK,WACJc,GAAQ,EACV,IACCb,OAAM,SAACC,GACNc,QAAQZ,MAAM,sCAAuCF,GACrDY,GAAQ,EACV,GACJ,GACF,uCAgB4C,WAC1C,IAAMG,EAAkBC,EAAWA,YAAC,mCAAmCC,UAAY,KAMnF,OAL0BzB,EAAKA,MAAC0B,OAAOC,aAAaC,kBAAkB5B,EAAKA,MAAC6B,YAGtCC,MAAK,SAACC,GAAW,OAAAA,EAAON,WAAaF,CAApB,IAG9CA,EAEA,IAEX,wCAE6C,WAC3C,IAAMA,EAAkBC,EAAWA,YAAC,oCAAoCC,UAAY,KAMpF,OAL2BzB,EAAKA,MAAC0B,OAAOC,aAAaK,mBAAmBhC,EAAKA,MAAC6B,YAGvCC,MAAK,SAACC,GAAW,OAAAA,EAAON,WAAaF,CAApB,IAG/CA,EAEA,IAEX,uCAxC4C,WAC1C,IAAMA,EAAkBC,EAAWA,YAAC,mCAAmCC,UAAY,KAMnF,OAL0BzB,EAAKA,MAAC0B,OAAOC,aAAaM,kBAAkBjC,EAAKA,MAAC6B,YAGtCC,MAAK,SAACC,GAAW,OAAAA,EAAON,WAAaF,CAApB,IAG9CA,EAEA,IAEX,8BAzImC,SAAUW,GAC3C,IAM4BC,EACpBR,EAPJS,GAAgB,EAEhBC,GAAY,EACZC,GAA8B,EAC9BC,GAA0B,EAEFJ,EA8CT,WACjB,IAAMK,EAAwB,CAC5BnC,MAAO+B,EACPK,SAAUH,EACVjB,MAAOgB,EACPK,SAAUH,GAGZ1C,EAAM8C,KAAO9C,EAAM8C,IAAI,oBAAqBH,GAC5CN,GACF,EAvDQP,EAAkC,GAExCiB,UAAUjB,aAAakB,mBAAmBvC,MAAK,SAACwC,GAC9CA,EAAQC,SAAQ,SAAUhB,GACxB,IAAIiB,GAAO,EAEXrB,EAAaoB,SAAQ,SAAUE,GACzBA,EAAExB,WAAaM,EAAON,UAAYwB,EAAEC,OAASnB,EAAOmB,OACtDF,GAAO,EAEX,IAEIA,IAIgB,eAAhBjB,EAAOmB,MAA0BX,IACnCA,GAA0B,GAER,eAAhBR,EAAOmB,MAA0BZ,IACnCA,GAA8B,GAGZ,eAAhBP,EAAOmB,OACTd,GAAgB,GAGdL,EAAOmB,KAIS,eAAhBnB,EAAOmB,OACTb,GAAY,GAGdV,EAAawB,KAAKpB,GACpB,IAEII,GACFA,GAEJ,GAeJ"}
|
|
1
|
+
{"version":3,"file":"devices.js","sources":["../../../src/lib/devices/devices.ts"],"sourcesContent":["// Copyright (C) 2024 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport {\n MediaPermissionsError,\n MediaPermissionsErrorType,\n requestMediaPermissions,\n} from 'mic-check'\nimport JanusLib from '../webrtc/janus'\nimport { JanusTypes } from '../../types'\nimport { store } from '../../store'\nimport { isPhysical } from '../user/default_device'\nimport { getJSONItem, setJSONItem } from '../../utils'\nimport { eventDispatch} from '../../utils/genericFunctions/eventDispatch'\n\nconst Janus: JanusTypes = JanusLib\n\nexport const getSupportedDevices = function (origCallback: () => void) {\n let hasMicrophone = false\n let hasSpeakers = false\n let hasWebcam = false\n let isMicrophoneAlreadyCaptured = false\n let isWebcamAlreadyCaptured = false\n\n function checkDeviceSupport(callback: () => void) {\n const mediaDevices: MediaDeviceInfo[] = []\n\n navigator.mediaDevices.enumerateDevices().then((devices: MediaDeviceInfo[]) => {\n devices.forEach(function (device: MediaDeviceInfo) {\n let skip = false\n\n mediaDevices.forEach(function (d: MediaDeviceInfo) {\n if (d.deviceId === device.deviceId && d.kind === device.kind) {\n skip = true\n }\n })\n\n if (skip) {\n return\n }\n\n if (device.kind === 'videoinput' && !isWebcamAlreadyCaptured) {\n isWebcamAlreadyCaptured = true\n }\n if (device.kind === 'audioinput' && !isMicrophoneAlreadyCaptured) {\n isMicrophoneAlreadyCaptured = true\n }\n\n if (device.kind === 'audioinput') {\n hasMicrophone = true\n }\n\n if (device.kind === 'audiooutput') {\n hasSpeakers = true\n }\n\n if (device.kind === 'videoinput') {\n hasWebcam = true\n }\n\n mediaDevices.push(device)\n })\n\n if (callback) {\n callback()\n }\n })\n }\n\n // check for microphone/camera support!\n checkDeviceSupport(function () {\n const supportedDevices: any = {\n audio: hasMicrophone,\n audioCap: isMicrophoneAlreadyCaptured,\n video: hasWebcam,\n videoCap: isWebcamAlreadyCaptured,\n }\n\n Janus.log && Janus.log('supportedDevices=', supportedDevices)\n origCallback()\n })\n}\n\nexport const checkMediaPermissions = function () {\n //Remove all media alerts if default_device is physical\n if (isPhysical()) {\n store.dispatch.alerts.removeAlert('browser_permissions')\n store.dispatch.alerts.removeAlert('user_permissions')\n store.dispatch.alerts.removeAlert('busy_camera')\n store.dispatch.alerts.removeAlert('unknown_media_permissions')\n return\n }\n\n requestMediaPermissions({ audio: true })\n .then(() => {\n // Can successfully access camera and microphone streams\n // Save permissions state on rematch to get access globally on the app\n })\n .catch((err: any) => {\n const { type } = err\n\n // Define error mappings for different types of media permission errors\n const errorMap: any = {\n [MediaPermissionsErrorType.SystemPermissionDenied]: {\n alert: 'browser_permissions',\n message: 'WebRTC: browser does not have permission to access camera or microphone',\n },\n [MediaPermissionsErrorType.UserPermissionDenied]: {\n alert: 'user_permissions',\n message: \"WebRTC: user didn't allow app to access camera or microphone\",\n },\n }\n\n // Get error details from map or use default error\n const error = errorMap[type] ?? {\n alert: 'unknown_media_permissions',\n message: \"WebRTC: can't access audio or camera on this device. unknown error\",\n }\n\n // Display alert only for non-physical devices\n store.dispatch.alerts.setAlert(error.alert)\n\n // Log error message if Janus logger is available\n if (Janus.error) {\n Janus.error(error.message)\n }\n })\n}\n\nexport const checkWebCamPermission = function (): Promise<boolean> {\n return new Promise((resolve) => {\n requestMediaPermissions({ video: true })\n .then(() => {\n resolve(true)\n })\n .catch((err: any) => {\n console.error('Error requesting webcam permission:', err)\n resolve(false)\n })\n })\n}\n\nexport const getCurrentVideoInputDeviceId = function () {\n const currentDeviceId = getJSONItem('phone-island-video-input-device').deviceId || null\n const videoInputDevices = store.select.mediaDevices.videoInputDevices(store.getState())\n\n // Check if the current device is still available\n const deviceFound = videoInputDevices.find((device) => device.deviceId === currentDeviceId)\n\n if (deviceFound) {\n return currentDeviceId\n } else {\n // Fallback to default device\n const defaultDevice = videoInputDevices.find(device => device.deviceId === 'default' || device.deviceId === '') || videoInputDevices[0]\n const fallbackDeviceId = defaultDevice ? defaultDevice.deviceId : 'default'\n\n if (currentDeviceId !== null && fallbackDeviceId !== currentDeviceId) {\n console.warn(`Video input device ${currentDeviceId} no longer available, falling back to default device`)\n // Update localStorage with the fallback device\n setJSONItem('phone-island-video-input-device', { deviceId: fallbackDeviceId })\n }\n\n return fallbackDeviceId\n }\n}\n\nexport const getCurrentAudioInputDeviceId = function () {\n const currentDeviceId = getJSONItem('phone-island-audio-input-device').deviceId || null\n const audioInputDevices = store.select.mediaDevices.audioInputDevices(store.getState())\n\n // Check if the current device is still available\n const deviceFound = audioInputDevices.find((device) => device.deviceId === currentDeviceId)\n\n if (deviceFound) {\n return currentDeviceId\n } else {\n // Fallback to default device\n const defaultDevice = audioInputDevices.find(device => device.deviceId === 'default' || device.deviceId === '') || audioInputDevices[0]\n const fallbackDeviceId = defaultDevice ? defaultDevice.deviceId : 'default'\n\n if (currentDeviceId !== null && fallbackDeviceId !== currentDeviceId) {\n console.warn(`Audio input device ${currentDeviceId} no longer available, falling back to default device`)\n // Update localStorage with the fallback device\n setJSONItem('phone-island-audio-input-device', { deviceId: fallbackDeviceId })\n }\n\n return fallbackDeviceId\n }\n}\n\nexport const getCurrentAudioOutputDeviceId = function () {\n const currentDeviceId = getJSONItem('phone-island-audio-output-device').deviceId || null\n const audioOutputDevices = store.select.mediaDevices.audioOutputDevices(store.getState())\n\n // Check if the current device is still available\n const deviceFound = audioOutputDevices.find((device) => device.deviceId === currentDeviceId)\n\n if (deviceFound) {\n return currentDeviceId\n } else {\n // Fallback to default device\n const defaultDevice = audioOutputDevices.find(device => device.deviceId === 'default' || device.deviceId === '') || audioOutputDevices[0]\n const fallbackDeviceId = defaultDevice ? defaultDevice.deviceId : 'default'\n\n if (currentDeviceId !== null && fallbackDeviceId !== currentDeviceId) {\n console.warn(`Audio output device ${currentDeviceId} no longer available, falling back to default device`)\n // Update localStorage with the fallback device\n setJSONItem('phone-island-audio-output-device', { deviceId: fallbackDeviceId })\n }\n\n return fallbackDeviceId\n }\n}\n"],"names":["Janus","JanusLib","isPhysical","store","dispatch","alerts","removeAlert","requestMediaPermissions","audio","then","catch","err","type","error","_b","_a","MediaPermissionsErrorType","SystemPermissionDenied","alert","message","UserPermissionDenied","setAlert","Promise","resolve","video","console","currentDeviceId","getJSONItem","deviceId","audioInputDevices","select","mediaDevices","getState","find","device","defaultDevice","fallbackDeviceId","warn","setJSONItem","audioOutputDevices","videoInputDevices","origCallback","callback","hasMicrophone","hasWebcam","isMicrophoneAlreadyCaptured","isWebcamAlreadyCaptured","supportedDevices","audioCap","videoCap","log","navigator","enumerateDevices","devices","forEach","skip","d","kind","push"],"mappings":"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"}
|