"use strict";(self.webpackChunktinode_webapp=self.webpackChunktinode_webapp||[]).push([[836],{6836:function(e,t,a){a.r(t);var n=a(1594),i=a.n(n),s=a(8181),r=a(6904),o=a(9027),h=a(3832),l=a(8589);const c=new Audio("audio/call-out.m4a");c.loop=!0;const d=new Audio("audio/call-end.m4a");d.loop=!0;const p=new Audio("audio/dialing.m4a"),m="video:muted",g="video:unmuted",C=(0,s.defineMessages)({already_in_call:{id:"already_in_call",defaultMessage:[{type:0,value:"You already in an ongoing call!"}]}});class u extends i().PureComponent{constructor(e){super(e),this.state={localStream:void 0,remoteStream:void 0,pc:void 0,dataChannel:void 0,previousOnInfo:void 0,waitingForPeer:!1,callInitialSetupComplete:!1,audioOnly:e.callAudioOnly,videoToggleInProgress:!1,remoteVideoLive:!1},this.localStreamConstraints={audio:!0,video:!e.callAudioOnly},this.isOutgoingCall=e.callState==h.No,this.containerRef=i().createRef(),this.localRef=i().createRef(),this.remoteRef=i().createRef(),this.remoteIceCandidatesCache=[],this.onInfo=this.onInfo.bind(this),this.start=this.start.bind(this),this.stop=this.stop.bind(this),this.createPeerConnection=this.createPeerConnection.bind(this),this.canSendOffer=this.canSendOffer.bind(this),this.drainRemoteIceCandidatesCache=this.drainRemoteIceCandidatesCache.bind(this),this.handleNegotiationNeededEvent=this.handleNegotiationNeededEvent.bind(this),this.handleICECandidateEvent=this.handleICECandidateEvent.bind(this),this.handleNewICECandidateMsg=this.handleNewICECandidateMsg.bind(this),this.handleICEConnectionStateChangeEvent=this.handleICEConnectionStateChangeEvent.bind(this),this.handleSignalingStateChangeEvent=this.handleSignalingStateChangeEvent.bind(this),this.handleICEGatheringStateChangeEvent=this.handleICEGatheringStateChangeEvent.bind(this),this.handleIceCandidateErrorEvent=this.handleIceCandidateErrorEvent.bind(this),this.handleTrackEvent=this.handleTrackEvent.bind(this),this.handleVideoOfferMsg=this.handleVideoOfferMsg.bind(this),this.handleVideoAnswerMsg=this.handleVideoAnswerMsg.bind(this),this.handleNewICECandidateMsg=this.handleNewICECandidateMsg.bind(this),this.reportError=this.reportError.bind(this),this.handleGetUserMediaError=this.handleGetUserMediaError.bind(this),this.stopTracks=this.stopTracks.bind(this),this.disconnectMedia=this.disconnectMedia.bind(this),this.handleCloseClick=this.handleCloseClick.bind(this),this.handleToggleCameraClick=this.handleToggleCameraClick.bind(this),this.handleToggleMicClick=this.handleToggleMicClick.bind(this),this.handleRemoteHangup=this.handleRemoteHangup.bind(this),this.handleVideoCallAccepted=this.handleVideoCallAccepted.bind(this),this.muteVideo=this.muteVideo.bind(this),this.unmuteVideo=this.unmuteVideo.bind(this),this.emptyVideoTrack=this.emptyVideoTrack.bind(this),this.handleDataChannelEvent=this.handleDataChannelEvent.bind(this),this.handleDataChannelError=this.handleDataChannelError.bind(this),this.handleDataChannelMessage=this.handleDataChannelMessage.bind(this),this.handleDataChannelOpen=this.handleDataChannelOpen.bind(this),this.handleDataChannelClose=this.handleDataChannelClose.bind(this),this.bounds={},this.dragStart=e=>{if(e.target.classList.contains("draggable")&&!window.matchMedia("(width<=640px)")&&this.props.minimized&&this.containerRef){e.stopPropagation(),this.containerRef.current.setPointerCapture(e.pointerId),this.containerRef.current.style.cursor="grabbing",this.bounds.left=this.containerRef.current.offsetLeft,this.bounds.top=this.containerRef.current.offsetTop,this.bounds.width=this.containerRef.current.offsetWidth,this.bounds.height=this.containerRef.current.offsetHeight;const t=this.containerRef.current.offsetParent;this.bounds.maxX=t.offsetWidth,this.bounds.maxY=t.offsetHeight}},this.drag=e=>{e.stopPropagation();const t=this.containerRef.current;this.props.minimized&&this.containerRef&&t.hasPointerCapture(e.pointerId)&&(this.bounds.left=Math.min(Math.max(this.bounds.left+e.movementX,0),this.bounds.maxX-this.bounds.width),this.bounds.top=Math.min(Math.max(this.bounds.top+e.movementY,0),this.bounds.maxY-this.bounds.height),t.style.left=`${this.bounds.left}px`,t.style.top=`${this.bounds.top}px`)},this.dragEnd=e=>{e.stopPropagation(),this.props.minimized&&this.containerRef&&(this.containerRef.current.releasePointerCapture(e.pointerId),this.containerRef.current.style.cursor="grab")}}componentDidMount(){const e=this.props.tinode.getTopic(this.props.topic);this.previousOnInfo=e.onInfo,e.onInfo=this.onInfo,this.props.callState!=h.No&&this.props.callState!=h.d1||!this.localRef.current||this.start(),this.containerRef&&(this.containerRef.current.addEventListener("pointerdown",this.dragStart),this.containerRef.current.addEventListener("pointermove",this.drag),this.containerRef.current.addEventListener("pointerup",this.dragEnd))}componentWillUnmount(){this.props.tinode.getTopic(this.props.topic).onInfo=this.previousOnInfo,this.stop(),this.containerRef&&(this.containerRef.current.removeEventListener("pointerdown",this.dragStart),this.containerRef.current.removeEventListener("pointermove",this.drag),this.containerRef.current.removeEventListener("pointerup",this.dragEnd))}handleVideoCallAccepted(e){c.pause();const t=this.createPeerConnection(!0),a=this.state.localStream;a.getTracks().forEach(e=>{t.addTrack(e,a),"video"==e.kind&&this.state.audioOnly&&(e.enabled=!1,e.stop(),a.removeTrack(e))})}onInfo(e){if("call"==e.what)switch(e.event){case"accept":this.handleVideoCallAccepted(e);break;case"answer":this.handleVideoAnswerMsg(e);break;case"ice-candidate":this.handleNewICECandidateMsg(e);break;case"hang-up":this.handleRemoteHangup(e);break;case"offer":this.handleVideoOfferMsg(e);break;case"ringing":c.play().catch(e=>{});break;default:console.warn("Unknown call event",e.event)}}emptyVideoTrack(){const e=Object.assign(document.createElement("canvas"),{width:640,height:480});e.getContext("2d").fillRect(0,0,640,480);const t=e.captureStream(0);return Object.assign(t.getVideoTracks()[0],{enabled:!1})}start(){this.state.localStream?this.props.onError(this.props.intl.formatMessage(C.already_in_call),"info"):this.props.callState!=h.d1?navigator.mediaDevices.getUserMedia(this.localStreamConstraints).then(e=>{this.localStreamConstraints.video||e.addTrack(this.emptyVideoTrack()),this.setState({localStream:e,waitingForPeer:!0}),this.localRef.current.srcObject=e,p.play(),this.props.onInvite(this.props.topic,this.props.seq,this.props.callState,this.props.callAudioOnly)}).catch(this.handleGetUserMediaError):this.props.onInvite(this.props.topic,this.props.seq,h.d1,this.props.callAudioOnly)}stop(){d.pause(),d.currentTime=0,c.pause(),c.currentTime=0,this.stopTracks(this.state.localStream),this.stopTracks(this.state.remoteStream),this.disconnectMedia(this.localRef.current),this.disconnectMedia(this.remoteRef.current),this.state.pc&&(this.state.pc.ontrack=null,this.state.pc.onremovetrack=null,this.state.pc.onremovestream=null,this.state.pc.onicecandidate=null,this.state.pc.oniceconnectionstatechange=null,this.state.pc.onsignalingstatechange=null,this.state.pc.onicegatheringstatechange=null,this.state.pc.onnegotiationneeded=null,this.state.pc.onicecandidateerror=null,this.state.pc.ondatachannel=null,!this.state.dataChannel||"open"!=this.state.dataChannel.readyState&&"connecting"!=this.state.dataChannel.readyState||this.state.dataChannel.close(),this.state.pc.close()),this.setState({pc:null,waitingForPeer:!1})}disconnectMedia(e){e&&(e.srcObject=null,e.src="")}stopTracks(e){if(!e)return;let t=e.getTracks();t&&t.forEach(e=>{e.stop(),e.enabled=!1})}handleDataChannelError(e){console.error("data channel error",e)}handleDataChannelMessage(e){switch(e.data){case m:this.setState({remoteVideoLive:!1},e=>{this.remoteRef.current.srcObject=this.state.remoteStream});break;case g:this.setState({remoteVideoLive:!0},e=>{this.remoteRef.current.srcObject=this.state.remoteStream})}}handleDataChannelOpen(e){this.state.audioOnly||e.target.send(g)}handleDataChannelClose(e){console.log("close data channel:",e)}handleDataChannelEvent(e){console.log("data channel event:",e);const t=e.channel;t.onerror=this.handleDataChannelError,t.onmessage=this.handleDataChannelMessage,t.onopen=this.handleDataChannelOpen,t.onclose=this.handleDataChannelClose,this.setState({dataChannel:t})}createPeerConnection(e){const t=this.props.tinode.getServerParam("iceServers",null),a=t?new RTCPeerConnection({iceServers:t}):new RTCPeerConnection;a.onicecandidate=this.handleICECandidateEvent,a.oniceconnectionstatechange=this.handleICEConnectionStateChangeEvent,a.onicegatheringstatechange=this.handleICEGatheringStateChangeEvent,a.onsignalingstatechange=this.handleSignalingStateChangeEvent,a.onnegotiationneeded=this.handleNegotiationNeededEvent,a.onicecandidateerror=this.handleIceCandidateErrorEvent,a.ontrack=this.handleTrackEvent,a.ondatachannel=this.handleDataChannelEvent;let n={pc:a,waitingForPeer:!1};if(e){const e=a.createDataChannel("events",{ordered:!0});e.onerror=this.handleDataChannelError,e.onmessage=this.handleDataChannelMessage,e.onopen=this.handleDataChannelOpen,e.onclose=this.handleDataChannelClose,n.dataChannel=e}return this.setState(n),a}handleVideoAnswerMsg(e){const t=new RTCSessionDescription(e.payload);this.state.pc.setRemoteDescription(t).then(e=>{this.setState({callInitialSetupComplete:!0},e=>this.drainRemoteIceCandidatesCache())}).catch(e=>this.reportError(e))}reportError(e){this.props.onError(e.message,"err")}canSendOffer(){return this.isOutgoingCall||this.state.callInitialSetupComplete}handleNegotiationNeededEvent(e){const t=e.target;this.canSendOffer()&&t.createOffer().then(e=>t.setLocalDescription(e)).then(e=>{this.props.onSendOffer(this.props.topic,this.props.seq,t.localDescription.toJSON())}).catch(e=>this.reportError(e))}handleIceCandidateErrorEvent(e){console.warn("ICE candidate error:",e)}handleICECandidateEvent(e){e.candidate&&this.props.onIceCandidate(this.props.topic,this.props.seq,e.candidate.toJSON())}handleNewICECandidateMsg(e){const t=new RTCIceCandidate(e.payload);this.state.callInitialSetupComplete?this.state.pc.addIceCandidate(t).catch(e=>{t.candidate&&this.reportError(e),console.warn("Error adding new ice candidate",t,e)}):this.remoteIceCandidatesCache.push(t)}drainRemoteIceCandidatesCache(){this.remoteIceCandidatesCache.forEach(e=>{this.state.pc.addIceCandidate(e).catch(t=>{e.candidate&&this.reportError(t),console.warn("Error adding cached ice candidate",e,t)})}),this.remoteIceCandidatesCache=[]}handleICEConnectionStateChangeEvent(e){switch(e.target.iceConnectionState){case"closed":case"failed":this.handleCloseClick()}}handleSignalingStateChangeEvent(e){"closed"==e.target.signalingState&&this.handleCloseClick()}handleICEGatheringStateChangeEvent(e){}handleTrackEvent(e){this.remoteRef.current.srcObject=e.streams[0],this.setState({remoteStream:e.streams[0]})}handleGetUserMediaError(e){switch(console.error("Error opening camera and/or microphone",e),e.name){case"NotFoundError":default:this.reportError(e);case"SecurityError":case"PermissionDeniedError":}this.handleCloseClick()}handleVideoOfferMsg(e){let t=null;const a=this.state.pc?this.state.pc:this.createPeerConnection(!1),n=new RTCSessionDescription(e.payload);a.setRemoteDescription(n).then(e=>navigator.mediaDevices.getUserMedia(this.localStreamConstraints)).then(e=>{let n;this.localStreamConstraints.video||(n=this.emptyVideoTrack(),e.addTrack(n)),t=e,this.localRef.current.srcObject=e,this.setState({localStream:e}),t.getTracks().forEach(e=>{a.addTrack(e,t)}),n&&(n.enabled=!1,n.stop(),e.removeTrack(n))}).then(e=>a.createAnswer()).then(e=>a.setLocalDescription(e)).then(e=>{this.props.onSendAnswer(this.props.topic,this.props.seq,a.localDescription.toJSON()),this.setState({callInitialSetupComplete:!0},e=>this.drainRemoteIceCandidatesCache())}).catch(this.handleGetUserMediaError)}handleRemoteHangup(){this.state.waitingForPeer?(this.setState({waitingForPeer:!1}),c.pause(),c.currentTime=0,d.loop=!0,d.play().catch(e=>{}),setTimeout(e=>{this.handleCloseClick()},2e3)):this.handleCloseClick()}handleCloseClick(){this.stop(),this.props.onHangup(this.props.topic,this.props.seq)}muteVideo(){if(!this.state.pc||!this.state.dataChannel)return;const e=this.state.localStream,t=e.getVideoTracks()[0];t.enabled=!1,t.stop(),e.removeTrack(t),this.state.dataChannel.send(m),this.setState({videoToggleInProgress:!1})}unmuteVideo(){this.state.pc&&this.state.dataChannel&&navigator.mediaDevices.getUserMedia({video:!0}).then(e=>{this.localRef.current.srcObject=null;const t=this.state.pc.getSenders().find(e=>"video"==e.track.kind),a=e.getVideoTracks()[0];return e.removeTrack(a),this.state.localStream.addTrack(a),t.replaceTrack(a)}).then(e=>{this.localRef.current.srcObject=this.state.localStream,this.state.dataChannel.send(g)}).catch(e=>this.handleGetUserMediaError(e)).finally(e=>{this.setState({videoToggleInProgress:!1})})}handleToggleCameraClick(){if(this.state.videoToggleInProgress)return;const e=this.state.localStream.getVideoTracks();this.setState({videoToggleInProgress:!0},t=>{e&&e.length>0&&e[0].enabled&&"live"==e[0].readyState?this.muteVideo():this.unmuteVideo(),this.setState({audioOnly:!this.state.audioOnly})})}handleToggleMicClick(){const e=this.state.localStream.getAudioTracks()[0];e.enabled=!e.enabled,this.forceUpdate()}render(){const e=this.state.localStream&&this.state.localStream.getAudioTracks(),t=!this.state.audioOnly&&this.state.localStream&&this.state.localStream.getVideoTracks(),a=!this.state.pc||!this.state.dataChannel||!(e&&e[0]),n=e&&e[0]&&e[0].enabled?"mic":"mic_off",h=t&&t[0]&&t[0].enabled&&"live"==t[0].readyState?"videocam":"videocam_off",c=(0,l.W5)(this.props.title,o.mu),d=this.state.waitingForPeer?" pulse":"";let p=!1;if(this.remoteRef.current&&this.remoteRef.current.srcObject&&this.state.remoteVideoLive){const e=this.remoteRef.current.srcObject;if(e.getVideoTracks().length>0){const t=e.getVideoTracks()[0];p=t.enabled&&"live"==t.readyState}}const m=this.props.minimized?"minimized":null,g=this.props.minimized?"fullscreen":"fullscreen_exit";return i().createElement("div",{id:"video-container",className:m,ref:this.containerRef},i().createElement("div",{id:"video-container-panel"},i().createElement("div",{className:"call-party self",disabled:this.state.audioOnly||this.props.minimized},i().createElement("video",{ref:this.localRef,autoPlay:!0,muted:!0,playsInline:!0}),i().createElement("div",{className:"caller-name inactive"},i().createElement(s.FormattedMessage,{id:"calls_you_label",defaultMessage:[{type:0,value:"You"}]}))),i().createElement("div",{className:"call-party peer",disabled:!p},p?i().createElement(i().Fragment,null,i().createElement("video",{ref:this.remoteRef,autoPlay:!0,playsInline:!0}),i().createElement("div",{className:"caller-name inactive"},c)):i().createElement(i().Fragment,null,i().createElement("audio",{ref:this.remoteRef,autoPlay:!0}),i().createElement("div",{className:`caller-card${d} draggable`},i().createElement("div",{className:"avatar-box"},i().createElement(r.A,{authorizeURL:this.props.tinode.authorizeURL,avatar:this.props.avatar,topic:this.props.topic,title:this.props.title})),i().createElement("div",{className:"caller-name"},c))))),i().createElement("button",{className:"full-screen",onClick:this.props.onToggleMinimize},i().createElement("i",{className:"material-icons"},g)),i().createElement("div",{id:"controls",className:m},i().createElement("button",{className:"danger",onClick:this.handleCloseClick},i().createElement("i",{className:"material-icons"},"call_end")),i().createElement("button",{className:"secondary",onClick:this.handleToggleCameraClick,disabled:a},i().createElement("i",{className:"material-icons"},h)),i().createElement("button",{className:"secondary",onClick:this.handleToggleMicClick,disabled:a},i().createElement("i",{className:"material-icons"},n))))}}t.default=(0,s.injectIntl)(u)}}]); //# sourceMappingURL=836.prod.js.map