{"version":3,"sources":["pages/DownloadPage.js","common/CustomLoader/CustomLoader.js","template/LoginTemplate/LoginTemplate.js","pages/LoginPage.js","pages/StreamPage.js","pages/MainPage.js","pages/RemotePage.js","pages/StreamWebPage.js","pages/MainWebPage.js","pages/RemoteWebPage.js","pages/DashboardPage.js","components/atom/icons/CircleCompleteIcon.jsx","components/atom/icons/CircleFailIcon.jsx","pages/SNSLogin.js","App.js","serviceWorker.js","index.js"],"names":["downloadUrl","DownloadPage","props","state","timer","percentage","updatePercentage","setState","setTimeout","this","console","log","window","location","href","bit","split","rand","Math","floor","random","length","replace","className","value","text","styles","buildStyles","rotation","strokeLinecap","textSize","pathTransitionDuration","pathColor","textColor","trailColor","backgroundColor","Component","CustomLoader","sizeUnit","size","color","loading","LoginTemplate","inputArea","LoginPage","nickname","loginStatus","strError","isRequested","account","password","verifyAccessToken","access_info","JSON","parse","sessionStorage","getItem","accessToken","access_token","fetch","method","headers","body","stringify","data","category","service","then","res","json","err","status","setItem","catch","requestSignIn","handleFormEvent","e","preventDefault","nextStatus","sendData","handleChange","target","name","nextProps","nextState","nextContext","login","onSubmit","TextField","error","helperText","key","id","label","type","autoComplete","margin","variant","onChange","autoFocus","Button","onClick","IconButton","aria-label","StreamPage","isConnected","isOpenedDataChannel","initializeWS","deviceAccessToken","device_access_token","uuidv1","client_type","sendWS","msg","refWS","sendMessage","onopenWS","onmessageWS","startToLive","onAnswerStream","onCandidateStream","createAnswerData","onAnswerData","onCandidateData","s","i","payload","channel_type","sdp","candidate","oncloseWS","opponent_dat","opponentDAT","setupPeerConnection","thisComponent","iceServers","ua","navigator","userAgent","toLowerCase","indexOf","streamConnection","RTCPeerConnection","onclose","ontrack","base","document","getElementById","video","srcObject","streams","addEventListener","videoWidth","videoHeight","onresize","event","rect","getBoundingClientRect","x","clientX","left","y","clientY","top","button","message","command","width","height","dataChannel","send","isMouseDown","onnegotiationneeded","isOpenedWebRTCRemote","onicecandidate","createAnswerSC","offer","streamLabel","handle","channelLabel","setRemoteDescription","RTCSessionDescription","createAnswer","answer","source","setLocalDescription","createOfferStream","createOffer","offerToReceiveAudio","offerToReceiveVideo","addIceCandidate","RTCIceCandidate","onCandidateSC","dataChannelLabel","dataConnection","oniceconnectionstatechange","ondatachannel","channel","onopen","onmessage","d","chunk","undefined","close","onClickPlayButton","onClickHomeButton","onClickBackButton","onClickRecentButton","device","clearSelectedDevice","url","onOpen","onMessage","onClose","reconnectIntervalInMilliSeconds","ref","Websocket","AppBar","position","justify","style","background","Toolbar","Typography","marginLeft","playsInline","autoPlay","MainPage","agentList","selectedDevice","GetAgentList","agent_list","GetSystemInformation","send_data","ice_servers","handleClickedListItem","List","sort","a","b","map","ListItem","ListItemText","primary","RemotePage","isLogin","logout","connectionCount","requestGetConnection","todayNewUserCount","androidConnectionCount","iosConnectionCount","agentConnectionCount","connection_number","today_new_user_count","android_connection_count","ios_connection_count","agent_connection_count","reload","CircleCompleteIcon","classes","classNames","viewBox","fill","xmlns","cx","cy","r","stroke","strokeWidth","strokeLinejoin","CircleFailIcon","SNSLogin","success","App","query","URLSearchParams","useLocation","search","get","param","RemoteWebPage","DashboardPage","Boolean","hostname","match","ReactDOM","render","StrictMode","serviceWorker","ready","registration","unregister"],"mappings":"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","file":"static/js/main.e41e81b2.chunk.js","sourcesContent":["import React, { Component } from 'react';\r\nimport AdSense from 'react-adsense';\r\nimport { CircularProgressbar, buildStyles } from 'react-circular-progressbar';\r\nimport 'react-circular-progressbar/dist/styles.css';\r\n\r\nconst downloadUrl = {\r\n \"32\" : [\r\n 'https://bit.ly/3i82zgr',\r\n 'https://bit.ly/3i82zgr',\r\n ],\r\n \"64\" : [\r\n 'https://bit.ly/3B0rD4V',\r\n\t'https://bit.ly/3B0rD4V',\r\n ]\r\n};\r\n\r\nclass DownloadPage extends Component {\r\n constructor(props) {\r\n super(props);\r\n };\r\n state = {\r\n timer: -1,\r\n percentage: 0,\r\n };\r\n\r\n updatePercentage = () => {\r\n const { updatePercentage } = this;\r\n const { percentage } = this.state;\r\n if ( this.state.percentage < 100 ) {\r\n this.setState({\r\n percentage: percentage + 1,\r\n })\r\n setTimeout(function () {\r\n updatePercentage()\r\n }, 1)\r\n } else {\r\n this.setState({\r\n timer: 0,\r\n })\r\n }\r\n }\r\n\r\n componentDidMount() {\r\n const { updatePercentage } = this;\r\n this.setState({\r\n timer: 0,\r\n })\r\n updatePercentage();\r\n }\r\n\r\n render() {\r\n const {timer, percentage} = this.state;\r\n\r\n console.log('SWS', 'URL:', window.location.href);\r\n let bit = window.location.href.split('bit=')[1];\r\n\r\n if (timer >= 0) {\r\n if (percentage === 100) {\r\n const rand = Math.floor(Math.random() * downloadUrl[bit].length);\r\n console.log('rand=', rand);\r\n window.location.replace(downloadUrl[bit][rand])\r\n // if (bit === '32') {\r\n // window.location.replace('http://bit.ly/2lukQMG')\r\n // } else if (bit === '64') {\r\n // window.location.replace('http://bit.ly/2lumBtg')\r\n // }\r\n }\r\n return (\r\n
\r\n
\r\n 피카부 설치 파일이 곧 다운로드됩니다.\r\n
\r\n
\r\n \r\n
\r\n {/*
*/}\r\n {/* */}\r\n {/*
*/}\r\n
\r\n );\r\n } else {\r\n return(\r\n
\r\n\r\n
\r\n )\r\n }\r\n }\r\n\r\n}\r\n\r\nexport default DownloadPage;\r\n","import React, {Component} from 'react';\r\nimport { ScaleLoader } from 'react-spinners';\r\nimport './CustomLoader.scss';\r\n\r\nclass CustomLoader extends Component {\r\n\r\n render() {\r\n return
\r\n \r\n
\r\n\r\n }\r\n}\r\nexport default CustomLoader;\r\n","import React, {Component} from 'react';\r\nimport './LoginTemplate.scss';\r\n\r\nclass LoginTemplate extends Component {\r\n render() {\r\n return (\r\n
\r\n
\r\n
\r\n
\r\n FLOWORK\r\n
\r\n
\r\n {this.props.inputArea}\r\n
\r\n
\r\n
\r\n )\r\n }\r\n}\r\n\r\nexport default LoginTemplate;","import React, {Component, Fragment} from 'react';\r\nimport CustomLoader from '../common/CustomLoader';\r\nimport LoginTemplate from '../template/LoginTemplate'\r\nimport Button from '@material-ui/core/Button';\r\nimport IconButton from '@material-ui/core/IconButton';\r\nimport ReturnIcon from '@material-ui/icons/KeyboardBackspace';\r\nimport TextField from '@material-ui/core/TextField';\r\n\r\nclass LoginPage extends Component {\r\n constructor(props) {\r\n super(props);\r\n };\r\n\r\n state = {\r\n nickname: '',\r\n loginStatus: '',\r\n strError: '',\r\n isRequested: false,\r\n account: '',\r\n password: '',\r\n };\r\n\r\n verifyAccessToken = () => {\r\n const access_info = JSON.parse(sessionStorage.getItem('access_info'));\r\n let accessToken = '';\r\n if (access_info) {\r\n accessToken = access_info.access_token;\r\n }\r\n if (accessToken && accessToken.length > 0) {\r\n\r\n fetch('/api/', {\r\n method: 'post',\r\n headers: {'Content-type': 'application/json'},\r\n body: JSON.stringify({\r\n data: {\r\n category: 'private',\r\n service: 'GetUserInformation',\r\n access_token: accessToken,\r\n }\r\n })\r\n }).then(\r\n res => {\r\n // console.log('service', res);\r\n if (res) {\r\n return res.json();\r\n }\r\n }\r\n ).then(\r\n json => {\r\n console.log('service OK', json);\r\n if (!json) {\r\n return;\r\n }\r\n if (json.err) {\r\n console.log('err', json.err);\r\n this.setState({\r\n loginStatus: 'Login',\r\n })\r\n } else {\r\n // json.data.platform\r\n if (json.data.status === 'active') {\r\n sessionStorage.setItem('access_info', JSON.stringify(json.data));\r\n this.setState({\r\n nickname: json.data.nickname,\r\n loginStatus: 'LoginCompleted',\r\n })\r\n } else {\r\n this.setState({\r\n loginStatus: 'Login',\r\n })\r\n }\r\n }\r\n }).catch(\r\n err => {\r\n console.log(err)\r\n this.setState({\r\n loginStatus: 'Login',\r\n });\r\n }\r\n );\r\n } else {\r\n this.setState({\r\n loginStatus: 'Login',\r\n });\r\n }\r\n };\r\n\r\n requestSignIn = () => {\r\n this.setState({\r\n isRequested: true,\r\n });\r\n fetch('/api/', {\r\n method: 'post',\r\n headers: {'Content-type': 'application/json'},\r\n body: JSON.stringify({\r\n data: {\r\n category: 'public',\r\n service: 'SignIn',\r\n account: this.state.account,\r\n password: this.state.password,\r\n }\r\n })\r\n }).then(res => {\r\n console.log('service', res);\r\n if (res) {\r\n return res.json();\r\n }\r\n }).then(json => {\r\n if (!json) {\r\n return;\r\n }\r\n this.setState({\r\n isRequested: false,\r\n });\r\n if (json.err) {\r\n this.setState({\r\n strError: json.err,\r\n });\r\n } else {\r\n sessionStorage.setItem('access_info', JSON.stringify(json.data));\r\n\r\n this.setState({\r\n nickname: json.data.nickname,\r\n loginStatus: 'LoginCompleted',\r\n strError: '',\r\n })\r\n }\r\n }).catch(err => {\r\n console.log(err);\r\n });\r\n };\r\n\r\n handleFormEvent = (e, status) => {\r\n e.preventDefault();\r\n if (this.state.isRequested) {\r\n return;\r\n }\r\n const {loginStatus} = this.state;\r\n const { requestSignIn } = this;\r\n\r\n let nextStatus = status;\r\n let sendData = null;\r\n\r\n if (loginStatus === 'GetUserStatus') {\r\n sendData = {\r\n category: 'public',\r\n service: 'GetUserStatus',\r\n account: this.state.account,\r\n };\r\n } else if (loginStatus === 'SignIn') {\r\n requestSignIn();\r\n return;\r\n }\r\n\r\n this.setState({\r\n isRequested: true,\r\n });\r\n fetch('/api/', {\r\n method: 'post',\r\n headers: {'Content-type': 'application/json'},\r\n body: JSON.stringify({\r\n data: sendData\r\n })\r\n }).then(res => {\r\n console.log('service', res);\r\n if (res) {\r\n return res.json();\r\n }\r\n }).then(json => {\r\n if (!json) {\r\n return;\r\n }\r\n // console.log('service OK 1', send_data.service, json);\r\n // let start = new Date().getTime();\r\n // while (new Date().getTime() < start + 3000);\r\n\r\n this.setState({\r\n isRequested: false,\r\n });\r\n if (json.err) {\r\n console.log('service 실패', sendData.service, status, json);\r\n this.setState({\r\n strError: json.err,\r\n });\r\n } else {\r\n console.log('서비스 호출 성공', sendData.service, status, json);\r\n if (loginStatus === 'GetUserStatus') {\r\n this.setState({\r\n loginStatus: nextStatus,\r\n strError: '',\r\n })\r\n } else {\r\n console.log('service OK 3', sendData.service, json);\r\n // json.data.platform\r\n this.setState({\r\n loginStatus: nextStatus,\r\n strError: '',\r\n })\r\n }\r\n }\r\n }).catch(err => {\r\n console.log(err);\r\n });\r\n };\r\n\r\n handleChange = (e) => {\r\n this.setState({\r\n [e.target.name]: e.target.value\r\n })\r\n };\r\n\r\n componentDidMount() {\r\n const {verifyAccessToken} = this;\r\n verifyAccessToken()\r\n };\r\n\r\n shouldComponentUpdate(nextProps, nextState, nextContext) {\r\n const {loginStatus} = nextState;\r\n\r\n if (loginStatus === 'LoginCompleted') {\r\n if (nextState.isRequested === false) {\r\n this.props.login({\r\n account: nextState.account,\r\n nickname: nextState.nickname,\r\n });\r\n return false\r\n }\r\n }\r\n return true\r\n };\r\n\r\n render() {\r\n let inputArea = null;\r\n\r\n const {loginStatus} = this.state;\r\n const {handleChange, handleFormEvent} = this;\r\n switch (loginStatus) {\r\n case 'SignIn':\r\n inputArea = \r\n {this.state.isRequested ?\r\n
\r\n \r\n
:\r\n
handleFormEvent(e, 'LoginCompleted')}>\r\n 0}\r\n helperText={this.state.strError.length > 0 ? '비밀번호가 일치하지 않습니다' : '비밀번호를 입력하세요'}\r\n key=\"outlined-password-input\"\r\n id=\"outlined-password-input\"\r\n className='signin-input'\r\n label=\"Password\"\r\n type=\"password\"\r\n name=\"password\"\r\n autoComplete=\"current-password\"\r\n margin=\"normal\"\r\n variant=\"outlined\"\r\n onChange={handleChange}\r\n autoFocus\r\n />\r\n handleFormEvent(e, 'LoginCompleted')}>\r\n 로그인\r\n \r\n this.setState({strError: '', loginStatus: 'GetUserStatus'})}>\r\n \r\n \r\n \r\n }\r\n
;\r\n break;\r\n case 'GetUserStatus':\r\n inputArea = \r\n {this.state.isRequested ?\r\n
\r\n \r\n
:\r\n
handleFormEvent(e, 'SignIn')}>\r\n 0}\r\n helperText={this.state.strError.length > 0 ? '존재하지 않는 아이디입니다' : '아이디를 입력하세요'}\r\n key=\"outlined-account-input\"\r\n id=\"outlined-account-input\"\r\n className='signin-input'\r\n label=\"아이디\"\r\n name=\"account\"\r\n margin=\"normal\"\r\n variant=\"outlined\"\r\n value={this.state.account}\r\n onChange={handleChange}\r\n autoFocus\r\n />\r\n handleFormEvent(e, 'SignIn')}>\r\n 다음\r\n \r\n this.setState({strError: '', loginStatus: 'Login'})}>\r\n \r\n \r\n \r\n }\r\n
;\r\n break;\r\n case 'Login':\r\n inputArea = \r\n
\r\n this.setState({loginStatus: 'GetUserStatus'})}>\r\n 로그인\r\n \r\n ;\r\n break;\r\n default:\r\n inputArea = \r\n \r\n ;\r\n break;\r\n }\r\n\r\n\r\n return \r\n \r\n }\r\n\r\n}\r\n\r\nexport default LoginPage;","import React, {Component, Fragment} from 'react';\r\nimport CustomLoader from \"../common/CustomLoader\";\r\nimport Websocket from 'react-websocket';\r\nimport uuidv1 from 'uuid/v1';\r\nimport AppBar from '@material-ui/core/AppBar';\r\nimport Toolbar from '@material-ui/core/Toolbar';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport IconButton from '@material-ui/core/IconButton';\r\nimport PlayCircleFilledIcon from '@material-ui/icons/PlayCircleFilled';\r\nimport CancelIcon from '@material-ui/icons/Cancel';\r\nimport HomeIcon from '@material-ui/icons/Home';\r\nimport ArrowBackIcon from '@material-ui/icons/ArrowBack';\r\nimport FilterNoneIcon from '@material-ui/icons/FilterNone';\r\n\r\nconst wsHostUrl = 'wss://flowork.ai/ws';\r\nconst reconnectIntervalInMilliSeconds = 1000;\r\n\r\nclass StreamPage extends Component {\r\n constructor(props) {\r\n super(props);\r\n this.refWS = null;\r\n this.streamConnection = null;\r\n this.dataConnection = null;\r\n this.dataChannel = null;\r\n this.dataChannelLabel = '';\r\n this.opponentDAT = '';\r\n this.isMouseDown = false;\r\n this.chunk = '';\r\n };\r\n\r\n state = {\r\n isRequested: false,\r\n isConnected: false,\r\n isOpenedDataChannel: false,\r\n };\r\n initializeWS = (service) => {\r\n const access_info = JSON.parse(sessionStorage.getItem('access_info'));\r\n let accessToken = '';\r\n let deviceAccessToken = '';\r\n if (access_info) {\r\n accessToken = access_info.access_token;\r\n deviceAccessToken = access_info.device_access_token\r\n }\r\n if (!deviceAccessToken || deviceAccessToken.length === 0) {\r\n deviceAccessToken = uuidv1();\r\n access_info.device_access_token = deviceAccessToken;\r\n sessionStorage.setItem('access_info', JSON.stringify(access_info));\r\n }\r\n let sendData = {\r\n category: 'ws',\r\n service: service,\r\n access_token: accessToken,\r\n client_type: 'chrome',\r\n device_access_token: deviceAccessToken,\r\n\r\n };\r\n this.sendWS({\r\n data: sendData\r\n });\r\n };\r\n sendWS = (msg) => {\r\n if (this.refWS) {\r\n console.log('SWS', 'send', msg);\r\n this.refWS.sendMessage(JSON.stringify(msg));\r\n }\r\n };\r\n onopenWS = () => {\r\n console.log('SWS', 'onopenWS');\r\n const {initializeWS} = this;\r\n initializeWS('Register')\r\n };\r\n onmessageWS = (e) => {\r\n // console.log('onmessageWS - 1', e);\r\n const {startToLive, onAnswerStream, onCandidateStream, createAnswerData, onAnswerData, onCandidateData} = this;\r\n\r\n if (e) {\r\n let s = e.split('\\n');\r\n for (let i = 0; i < s.length; i++) {\r\n let payload = JSON.parse(s);\r\n // console.log(\"onmessageWS - 2\", payload);\r\n if (payload.data) {\r\n const service = payload.data.service;\r\n if (service === 'RegisterComplete') {\r\n startToLive();\r\n } else if (service === 'Answer') {\r\n console.log(\"onmessageWS - 2\", payload);\r\n if (payload.data.channel_type === 'stream') {\r\n onAnswerStream(payload.data.sdp);\r\n } else {\r\n onAnswerData(payload.data.sdp);\r\n }\r\n } else if (service === 'Candidate') {\r\n // CreateAnswer 보다 candidate 이 먼저 응답이 오면 이 candidate은 버려진다.\r\n // 그래서 접속이 자꾸 실패함. candidate 에 대해 딜레이를 줬음. 나중에 더 나이스한 해결책이 필요함\r\n if (payload.data.channel_type === 'stream') {\r\n setTimeout(function () {\r\n onCandidateStream(payload.data.candidate.candidate);\r\n }, 1000);\r\n } else {\r\n setTimeout(function () {\r\n onCandidateData(payload.data.candidate.candidate);\r\n }, 1000);\r\n }\r\n } else if (service === 'Offer') {\r\n createAnswerData(payload.data.sdp, payload.data.label);\r\n }\r\n }\r\n }\r\n }\r\n };\r\n oncloseWS = () => {\r\n console.log('SWS', 'oncloseWS');\r\n };\r\n startToLive = () => {\r\n const {sendWS} = this;\r\n const access_info = JSON.parse(sessionStorage.getItem('access_info'));\r\n let accessToken = '';\r\n let deviceAccessToken = '';\r\n if (access_info) {\r\n accessToken = access_info.access_token;\r\n deviceAccessToken = access_info.device_access_token\r\n }\r\n\r\n sendWS({\r\n data: {\r\n category: 'ws',\r\n service: 'StartToLive',\r\n access_token: accessToken,\r\n device_access_token: deviceAccessToken,\r\n opponent_dat: this.opponentDAT,\r\n channel_type: \"data\",\r\n }\r\n });\r\n };\r\n setupPeerConnection = () => {\r\n const {sendWS} = this;\r\n const thisComponent = this;\r\n const {iceServers} = this.props;\r\n const access_info = JSON.parse(sessionStorage.getItem('access_info'));\r\n let accessToken = '';\r\n let deviceAccessToken = '';\r\n if (access_info) {\r\n accessToken = access_info.access_token;\r\n deviceAccessToken = access_info.device_access_token;\r\n }\r\n let ua = navigator.userAgent.toLowerCase();\r\n console.log(ua);\r\n if (ua.indexOf('safari') !== -1) {\r\n if (ua.indexOf('chrome') > -1) {\r\n // Chrome\r\n this.streamConnection = new RTCPeerConnection(iceServers)\r\n } else {\r\n // Safari\r\n this.streamConnection = new RTCPeerConnection({\r\n iceServers: [\r\n {\r\n \"urls\": \"stun:stun.l.google.com:19302\"\r\n }\r\n ]\r\n });\r\n }\r\n } else {\r\n this.streamConnection = new RTCPeerConnection(iceServers)\r\n }\r\n console.log('SWS', 'stream', this.streamConnection);\r\n\r\n this.streamConnection.onclose = (e) => {\r\n console.log('streamConnection', 'onclose', e);\r\n };\r\n this.streamConnection.ontrack = (e) => {\r\n const base = document.getElementById('viewer-base');\r\n const video = document.getElementById('app-video');\r\n const thisComponent = this;\r\n if (video.srcObject !== e.streams[0]) {\r\n video.srcObject = e.streams[0];\r\n console.log('received remote stream');\r\n video.addEventListener('loadedmetadata', function () {\r\n console.log(`Remote video videoWidth: ${this.videoWidth}px, videoHeight: ${this.videoHeight}px`);\r\n });\r\n video.onresize = () => {\r\n console.log(`Remote video size changed to ${video.videoWidth}x${video.videoHeight}`);\r\n // We'll use the first onsize callback as an indication that video has started\r\n // playing out.\r\n };\r\n video.addEventListener('mousedown', function (event) {\r\n const rect = video.getBoundingClientRect()\r\n const x = event.clientX - rect.left;\r\n const y = event.clientY - rect.top;\r\n // console.log(\"mousedown\", \"x: \" + x + \" y: \" + y);\r\n // console.log(\"width: \" + rect.width + \" height: \" + rect.height);\r\n if (event.button === 0) {\r\n const message = JSON.stringify({\r\n command: 'mouse_down',\r\n x: (x / rect.width) + '',\r\n y: (y / rect.height) + '',\r\n });\r\n // console.log(message);\r\n thisComponent.dataChannel.send(message);\r\n thisComponent.isMouseDown = true\r\n }\r\n });\r\n video.addEventListener('mouseup', function (event) {\r\n const rect = video.getBoundingClientRect()\r\n const x = event.clientX - rect.left;\r\n const y = event.clientY - rect.top;\r\n // console.log(\"mouseup\", \"x: \" + x + \" y: \" + y);\r\n // console.log(\"width: \" + rect.width + \" height: \" + rect.height);\r\n if (event.button === 0) {\r\n const message = JSON.stringify({\r\n command: 'mouse_up',\r\n x: (x / rect.width) + '',\r\n y: (y / rect.height) + '',\r\n });\r\n // console.log(message);\r\n thisComponent.dataChannel.send(message);\r\n }\r\n });\r\n video.addEventListener('mousemove', function (event) {\r\n const rect = video.getBoundingClientRect()\r\n const x = event.clientX - rect.left;\r\n const y = event.clientY - rect.top;\r\n if (thisComponent.isMouseDown) {\r\n const message = JSON.stringify({\r\n command: 'mouse_move',\r\n x: (x / rect.width) + '',\r\n y: (y / rect.height) + '',\r\n });\r\n // console.log(message);\r\n thisComponent.dataChannel.send(message);\r\n }\r\n // console.log(\"mousemove\", \"x: \" + x + \" y: \" + y);\r\n // console.log(\"width: \" + rect.width + \" height: \" + rect.height);\r\n });\r\n document.addEventListener('mouseup', function (event) {\r\n thisComponent.isMouseDown = false;\r\n })\r\n base.addEventListener('mousemove', function (event) {\r\n // console.log(\"fab mousemove:\", fab.style.top, fab.style.left, event.clientX, event.clientY);\r\n });\r\n }\r\n };\r\n this.streamConnection.onnegotiationneeded = () => {\r\n thisComponent.setState({\r\n isOpenedWebRTCRemote: true,\r\n });\r\n };\r\n this.streamConnection.onicecandidate = function (e) {\r\n console.log('SWS', 'stream candidate', e);\r\n if (e.candidate) {\r\n thisComponent.dataChannel.send(JSON.stringify({\r\n data: {\r\n category: 'ws',\r\n service: 'Candidate',\r\n access_token: accessToken,\r\n opponent_dat: deviceAccessToken,\r\n channel_type: \"stream\",\r\n candidate: {\r\n type: 'candidate',\r\n candidate: e.candidate,\r\n },\r\n }\r\n }));\r\n }\r\n };\r\n };\r\n\r\n createAnswerSC = (offer, opponentDAT, streamLabel, handle) => {\r\n const thisComponent = this;\r\n const {sendWS, setupPeerConnection} = this;\r\n const channelLabel = uuidv1();\r\n const access_info = JSON.parse(sessionStorage.getItem('access_info'));\r\n let accessToken = '';\r\n let deviceAccessToken = '';\r\n if (access_info) {\r\n accessToken = access_info.access_token;\r\n deviceAccessToken = access_info.device_access_token\r\n }\r\n let ua = navigator.userAgent.toLowerCase();\r\n\r\n setupPeerConnection();\r\n\r\n const {streamConnection} = this;\r\n thisComponent.setState({\r\n isConnected: true,\r\n });\r\n streamConnection.setRemoteDescription(new RTCSessionDescription(offer));\r\n streamConnection.createAnswer().then(function (answer) {\r\n // console.log('--------------> 3', opponentDAT, thisComponent.nodes[opponentDAT].dc)\r\n // console.log('sc', 'createAnswer', deviceAccessToken, JSON.stringify(answer));\r\n thisComponent.dataChannel.send(JSON.stringify({\r\n data: {\r\n category: 'ws',\r\n service: 'Answer',\r\n channel_type: 'stream',\r\n opponent_dat: deviceAccessToken,\r\n source: ua,\r\n handle: handle,\r\n label: channelLabel,\r\n sdp: answer,\r\n },\r\n }));\r\n streamConnection.setLocalDescription(answer);\r\n }).catch(function (error) {\r\n console.log('SWS', 'An error has occurred.', error);\r\n });\r\n };\r\n createOfferStream = () => {\r\n const thisComponent = this;\r\n const {sendWS, setupPeerConnection} = this;\r\n\r\n setupPeerConnection();\r\n\r\n const {streamConnection} = this;\r\n streamConnection.createOffer({\r\n offerToReceiveAudio: false, offerToReceiveVideo: true,\r\n }).then(function (offer) {\r\n const access_info = JSON.parse(sessionStorage.getItem('access_info'));\r\n let accessToken = '';\r\n let deviceAccessToken = '';\r\n if (access_info) {\r\n accessToken = access_info.access_token;\r\n deviceAccessToken = access_info.device_access_token\r\n }\r\n\r\n // console.log('thisComponent.opponentDAT', thisComponent.opponentDAT);\r\n let payload = {\r\n data: {\r\n category: 'ws',\r\n service: 'Offer',\r\n access_token: accessToken,\r\n channel_type: \"stream\",\r\n opponent_dat: thisComponent.opponentDAT,\r\n label: deviceAccessToken,\r\n sdp: offer,\r\n }\r\n };\r\n sendWS(payload);\r\n streamConnection.setLocalDescription(offer);\r\n }).catch(function (error) {\r\n console.log('SWS', 'An error has occurred.', error);\r\n });\r\n thisComponent.setState({\r\n isConnected: true,\r\n })\r\n };\r\n onAnswerStream = (answer) => {\r\n this.streamConnection.setRemoteDescription(new RTCSessionDescription(answer));\r\n };\r\n onCandidateStream = (candidate) => {\r\n this.streamConnection.addIceCandidate(new RTCIceCandidate(candidate));\r\n };\r\n onCandidateSC = (candidate) => {\r\n console.log('candidate', this.streamConnection);\r\n if (candidate.candidate && candidate.candidate.length > 0) {\r\n this.streamConnection.addIceCandidate(candidate).catch(e => {\r\n console.log('Failure during addIceCandidate(): ' + e.name);\r\n });\r\n }\r\n };\r\n createAnswerData = (offer, label) => {\r\n const {iceServers} = this.props;\r\n this.dataChannelLabel = label;\r\n let ua = navigator.userAgent.toLowerCase();\r\n console.log(ua);\r\n if (ua.indexOf('safari') !== -1) {\r\n if (ua.indexOf('chrome') > -1) {\r\n // Chrome\r\n console.log('SWS', 'Safari Test 1');\r\n this.dataConnection = new RTCPeerConnection(iceServers)\r\n } else {\r\n // Safari\r\n console.log('SWS', 'Safari Test 2');\r\n this.dataConnection = new RTCPeerConnection({\r\n iceServers: [\r\n {\r\n \"urls\": \"stun:stun.l.google.com:19302\"\r\n }\r\n ]\r\n });\r\n }\r\n } else {\r\n console.log('SWS', 'Safari Test 3');\r\n this.dataConnection = new RTCPeerConnection(iceServers)\r\n }\r\n\r\n console.log('SWS', this.dataConnection);\r\n\r\n const access_info = JSON.parse(sessionStorage.getItem('access_info'));\r\n let accessToken = '';\r\n let deviceAccessToken = '';\r\n if (access_info) {\r\n accessToken = access_info.access_token;\r\n deviceAccessToken = access_info.device_access_token\r\n }\r\n\r\n const thisComponent = this;\r\n const {dataConnection, createAnswerSC} = this;\r\n\r\n // console.log(offer);\r\n // const d = JSON.parse(offer);\r\n thisComponent.dataConnection.setRemoteDescription(new RTCSessionDescription(offer));\r\n thisComponent.dataConnection.createAnswer(function (answer) {\r\n thisComponent.dataConnection.setLocalDescription(answer);\r\n let payload = {\r\n data: {\r\n category: 'ws',\r\n service: 'Answer',\r\n access_token: accessToken,\r\n opponent_dat: thisComponent.opponentDAT,\r\n label: thisComponent.dataChannelLabel,\r\n channel_type: \"data\",\r\n sdp: answer,\r\n }\r\n };\r\n thisComponent.sendWS(payload)\r\n }, function (error) {\r\n console.log('createAnswer', error);\r\n });\r\n thisComponent.dataConnection.oniceconnectionstatechange = e => {\r\n console.log('dataConnection oniceconnectionstatechange', e);\r\n };\r\n thisComponent.dataConnection.onicecandidate = function (e) {\r\n if (e.candidate) {\r\n thisComponent.sendWS({\r\n data: {\r\n category: 'ws',\r\n service: 'Candidate',\r\n access_token: accessToken,\r\n opponent_dat: thisComponent.opponentDAT,\r\n label: thisComponent.dataChannelLabel,\r\n channel_type: 'data',\r\n candidate: {\r\n type: 'candidate',\r\n candidate: e.candidate,\r\n },\r\n }\r\n });\r\n }\r\n };\r\n thisComponent.dataConnection.onnegotiationneeded = e => {\r\n console.log('onnegotiationneeded', e);\r\n };\r\n thisComponent.dataConnection.ondatachannel = (e) => {\r\n console.log('ondatachannel');\r\n thisComponent.dataChannel = e.channel;\r\n thisComponent.dataChannel.onclose = () => {\r\n console.log('remoteDataChannel has closed:', thisComponent.dataChannel.label);\r\n };\r\n thisComponent.dataChannel.onopen = () => {\r\n console.log('remoteDataChannel has opened:', thisComponent.dataChannel.label);\r\n thisComponent.setState({\r\n isOpenedDataChannel: true,\r\n })\r\n thisComponent.dataChannel.send(JSON.stringify({\r\n data: {\r\n category: 'ws',\r\n service: 'RequestToOfferSC',\r\n opponent_dat: deviceAccessToken,\r\n channel_type: 'stream',\r\n },\r\n }));\r\n };\r\n thisComponent.dataChannel.onmessage = e => {\r\n // console.log('remoteDataChannel onmessage', e);\r\n let d;\r\n if (e.data === \"@PIKABU-CHUNK-START\") {\r\n thisComponent.chunk = \"\";\r\n return;\r\n } else if (thisComponent.chunk !== null && thisComponent.chunk !== undefined) {\r\n if (e.data === \"@PIKABU-CHUNK-END\") {\r\n d = JSON.parse(thisComponent.chunk);\r\n thisComponent.chunk = null;\r\n } else {\r\n thisComponent.chunk += e.data;\r\n return;\r\n }\r\n } else {\r\n d = JSON.parse(e.data);\r\n }\r\n // console.log('SWS-DEBUG-9098', d.data);\r\n if (d.data) {\r\n if (d.data.service === 'Offer') {\r\n console.log('Offer', d.data);\r\n if (thisComponent.streamConnection) {\r\n if (thisComponent.streamConnection) {\r\n console.log('sc close');\r\n thisComponent.streamConnection.close();\r\n }\r\n }\r\n createAnswerSC(d.data.sdp, d.data.opponent_dat, d.data.label, d.data.handle);\r\n } else if (d.data.service === 'Candidate') {\r\n this.onCandidateSC(d.data.candidate.candidate, d.data.opponent_dat, d.data.source);\r\n\r\n // setTimeout(() => {\r\n // onCandidateSC(d.data.candidate.candidate, d.data.opponent_dat, d.data.source);\r\n // }, 100);\r\n }\r\n } else {\r\n\r\n }\r\n };\r\n }\r\n\r\n // dataConnection.createOffer()\r\n // .then(function (offer) {\r\n // // console.log('thisComponent.opponentDAT', thisComponent.opponentDAT);\r\n // let payload = {\r\n // data: {\r\n // category: 'ws',\r\n // service: 'Offer',\r\n // access_token: accessToken,\r\n // channel_type: \"data\",\r\n // opponent_dat: thisComponent.opponentDAT,\r\n // label: deviceAccessToken,\r\n // sdp: offer,\r\n // }\r\n // };\r\n // thisComponent.sendWS(payload);\r\n // dataConnection.setLocalDescription(offer);\r\n // }).catch(function (error) {\r\n // console.log('SWS', 'An error has occurred.', error);\r\n // });\r\n };\r\n onAnswerData = (answer) => {\r\n this.dataConnection.setRemoteDescription(new RTCSessionDescription(answer));\r\n };\r\n onCandidateData = (candidate) => {\r\n this.dataConnection.addIceCandidate(new RTCIceCandidate(candidate));\r\n };\r\n\r\n onClickPlayButton = () => {\r\n console.log('Play & Next');\r\n const message = JSON.stringify({\r\n command: 'switch',\r\n });\r\n this.dataChannel.send(message);\r\n };\r\n onClickHomeButton = () => {\r\n console.log('Home');\r\n const message = JSON.stringify({\r\n command: 'home',\r\n });\r\n this.dataChannel.send(message);\r\n };\r\n onClickBackButton = () => {\r\n console.log('Back');\r\n const message = JSON.stringify({\r\n command: 'back',\r\n });\r\n this.dataChannel.send(message);\r\n };\r\n onClickRecentButton = () => {\r\n console.log('Recent');\r\n const message = JSON.stringify({\r\n command: 'recent',\r\n });\r\n this.dataChannel.send(message);\r\n };\r\n\r\n componentDidMount() {\r\n console.log(this.props.device);\r\n this.opponentDAT = this.props.device.device_access_token\r\n }\r\n\r\n render() {\r\n const {isRequested, isConnected, isOpenedDataChannel} = this.state;\r\n const {onopenWS, onmessageWS, oncloseWS} = this;\r\n const {onClickPlayButton, onClickBackButton, onClickHomeButton, onClickRecentButton} = this;\r\n const {clearSelectedDevice} = this.props;\r\n return (\r\n \r\n {isConnected === false ?\r\n \r\n : null\r\n }\r\n\r\n {\r\n this.refWS = Websocket;\r\n }}/>\r\n
\r\n {isRequested ?\r\n
\r\n \r\n
\r\n :\r\n null\r\n }\r\n
\r\n
\r\n \r\n \r\n \r\n Pikabu Web\r\n \r\n\r\n
\r\n {isOpenedDataChannel ?\r\n \r\n \r\n \r\n : null\r\n }\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n )\r\n }\r\n\r\n}\r\n\r\nexport default StreamPage;\r\n","import React, {Component, Fragment} from 'react';\r\nimport List from '@material-ui/core/List';\r\nimport ListItem from '@material-ui/core/ListItem';\r\nimport ListItemText from '@material-ui/core/ListItemText';\r\nimport CustomLoader from \"../common/CustomLoader\";\r\nimport StreamPage from \"./StreamPage\";\r\nimport AppBar from \"@material-ui/core/AppBar/AppBar\";\r\nimport Toolbar from \"@material-ui/core/Toolbar\";\r\nimport Typography from \"@material-ui/core/Typography\";\r\nimport IconButton from \"@material-ui/core/IconButton\";\r\nimport PlayCircleFilledIcon from \"@material-ui/core/SvgIcon/SvgIcon\";\r\n\r\nclass MainPage extends Component {\r\n constructor(props) {\r\n super(props);\r\n };\r\n\r\n state = {\r\n isRequested: true,\r\n agentList: [],\r\n selectedDevice: null,\r\n iceServers: {},\r\n };\r\n\r\n GetAgentList = () => {\r\n const access_info = JSON.parse(sessionStorage.getItem('access_info'));\r\n let accessToken = '';\r\n if (access_info) {\r\n accessToken = access_info.access_token;\r\n }\r\n\r\n this.setState({\r\n isRequested: true,\r\n });\r\n fetch('/api/', {\r\n method: 'post',\r\n headers: {'Content-type': 'application/json'},\r\n body: JSON.stringify({\r\n data: {\r\n category: 'private',\r\n service: 'GetAgentList',\r\n access_token: accessToken,\r\n }\r\n })\r\n }).then(res => {\r\n if (res) {\r\n return res.json();\r\n }\r\n }).then(json => {\r\n if (!json) {\r\n return;\r\n }\r\n let agentList = [];\r\n if (json.data && json.data.agent_list) {\r\n agentList = json.data.agent_list\r\n }\r\n this.setState({\r\n isRequested: false,\r\n agentList: agentList,\r\n });\r\n }).catch(err => {\r\n console.log(err);\r\n });\r\n };\r\n\r\n GetSystemInformation = () => {\r\n const access_info = JSON.parse(sessionStorage.getItem('access_info'));\r\n let accessToken = '';\r\n if (access_info) {\r\n accessToken = access_info.access_token;\r\n }\r\n let send_data = {\r\n category: 'private',\r\n service: 'GetSystemInformation',\r\n access_token: accessToken,\r\n };\r\n\r\n fetch('/api/', {\r\n method: 'post',\r\n headers: {'Content-type': 'application/json'},\r\n body: JSON.stringify({\r\n \"data\": send_data\r\n })\r\n })\r\n .then(res => {\r\n console.log('service', res);\r\n if (res) {\r\n return res.json();\r\n }\r\n })\r\n .then(json => {\r\n if (!json) {\r\n return;\r\n }\r\n if (json.err) {\r\n console.log('service 실패', send_data.service, json);\r\n } else {\r\n console.log('service 성공', send_data.service, json);\r\n this.setState({\r\n iceServers: {\r\n iceServers: json.data.ice_servers\r\n },\r\n })\r\n }\r\n })\r\n .catch(err => {\r\n console.log(err);\r\n });\r\n };\r\n handleClickedListItem = (e, value) => {\r\n e.preventDefault();\r\n console.log('value:', value)\r\n this.setState({\r\n selectedDevice: value,\r\n })\r\n };\r\n clearSelectedDevice = () => {\r\n this.setState({\r\n selectedDevice: null,\r\n })\r\n };\r\n\r\n componentWillMount() {\r\n this.GetSystemInformation()\r\n }\r\n componentDidMount() {\r\n const {GetAgentList} = this;\r\n GetAgentList();\r\n }\r\n\r\n render() {\r\n const {isRequested, selectedDevice} = this.state;\r\n const {handleClickedListItem, clearSelectedDevice} = this;\r\n\r\n return (\r\n \r\n {isRequested ?\r\n \r\n : (selectedDevice ?\r\n \r\n :
\r\n \r\n \r\n \r\n My Computers\r\n \r\n \r\n \r\n \r\n {\r\n this.state.agentList.sort(function (a, b) {\r\n if ( a.name < b.name ){\r\n return -1;\r\n }\r\n if ( a.name > b.name ){\r\n return 1;\r\n }\r\n return 0;\r\n }).map(value => {\r\n return (\r\n {\r\n handleClickedListItem(e, value)\r\n }}\r\n />\r\n );\r\n })\r\n }\r\n \r\n
)\r\n\r\n }\r\n
\r\n )\r\n }\r\n\r\n}\r\n\r\nexport default MainPage;","import React, {Component, Fragment} from 'react';\r\nimport LoginPage from \"./LoginPage\";\r\nimport MainPage from \"./MainPage\";\r\n\r\nclass RemotePage extends Component {\r\n constructor(props) {\r\n super(props);\r\n };\r\n state = {\r\n isLogin: false,\r\n };\r\n\r\n componentDidMount() {\r\n }\r\n\r\n login = () => {\r\n this.setState({\r\n isLogin: true,\r\n })\r\n }\r\n\r\n logout = () => {\r\n this.setState({\r\n isLogin: false,\r\n })\r\n }\r\n render() {\r\n const { isLogin } = this.state\r\n const { login, logout } = this;\r\n return (\r\n \r\n {isLogin ?\r\n \r\n \r\n \r\n :\r\n \r\n \r\n \r\n }\r\n\r\n \r\n )\r\n }\r\n\r\n}\r\n\r\nexport default RemotePage;","import React, {Component, Fragment} from 'react';\r\nimport CustomLoader from \"../common/CustomLoader\";\r\nimport Websocket from 'react-websocket';\r\nimport uuidv1 from 'uuid/v1';\r\nimport AppBar from '@material-ui/core/AppBar';\r\nimport Toolbar from '@material-ui/core/Toolbar';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport IconButton from '@material-ui/core/IconButton';\r\nimport PlayCircleFilledIcon from '@material-ui/icons/PlayCircleFilled';\r\nimport CancelIcon from '@material-ui/icons/Cancel';\r\nimport HomeIcon from '@material-ui/icons/Home';\r\nimport ArrowBackIcon from '@material-ui/icons/ArrowBack';\r\nimport FilterNoneIcon from '@material-ui/icons/FilterNone';\r\n\r\nconst wsHostUrl = 'wss://flowork.ai/ws';\r\nconst reconnectIntervalInMilliSeconds = 1000;\r\n\r\nclass StreamPage extends Component {\r\n constructor(props) {\r\n super(props);\r\n this.refWS = null;\r\n this.streamConnection = null;\r\n this.dataConnection = null;\r\n this.dataChannel = null;\r\n this.dataChannelLabel = '';\r\n this.opponentDAT = '';\r\n this.isMouseDown = false;\r\n };\r\n\r\n state = {\r\n isRequested: false,\r\n isConnected: false,\r\n isOpenedDataChannel: false,\r\n };\r\n initializeWS = (service) => {\r\n const access_info = JSON.parse(sessionStorage.getItem('access_info'));\r\n let accessToken = '';\r\n let deviceAccessToken = '';\r\n if (access_info) {\r\n accessToken = access_info.access_token;\r\n deviceAccessToken = access_info.device_access_token\r\n }\r\n if (!deviceAccessToken || deviceAccessToken.length === 0) {\r\n deviceAccessToken = uuidv1();\r\n access_info.device_access_token = deviceAccessToken;\r\n sessionStorage.setItem('access_info', JSON.stringify(access_info));\r\n }\r\n let sendData = {\r\n category: 'ws',\r\n service: service,\r\n access_token: accessToken,\r\n client_type: 'web',\r\n device_access_token: deviceAccessToken,\r\n\r\n };\r\n this.sendWS({\r\n data: sendData\r\n });\r\n };\r\n sendWS = (msg) => {\r\n if (this.refWS) {\r\n console.log('SWS', 'send', msg);\r\n this.refWS.sendMessage(JSON.stringify(msg));\r\n }\r\n };\r\n onopenWS = () => {\r\n console.log('SWS', 'onopenWS');\r\n const {initializeWS} = this;\r\n initializeWS('Register')\r\n };\r\n onmessageWS = (e) => {\r\n const {sendWS, onAnswerStream, onCandidateStream, createAnswerData, onAnswerData, onCandidateData} = this;\r\n const access_info = JSON.parse(sessionStorage.getItem('access_info'));\r\n let accessToken = '';\r\n let deviceAccessToken = '';\r\n if (access_info) {\r\n accessToken = access_info.access_token;\r\n deviceAccessToken = access_info.device_access_token\r\n }\r\n let payload = JSON.parse(e);\r\n if (payload.data) {\r\n const service = payload.data.service;\r\n if (service === 'RegisterComplete') {\r\n sendWS({\r\n data: {\r\n category: 'ws',\r\n service: 'StartToLive',\r\n access_token: accessToken,\r\n client_type: 'web',\r\n label: accessToken,\r\n opponent_dat: this.opponentDAT,\r\n device_access_token: deviceAccessToken,\r\n }\r\n });\r\n } else if (service === 'Answer') {\r\n console.log('SWS', 'onmessageWS', e);\r\n if (payload.data.channel_type === 'stream') {\r\n onAnswerStream(payload.data.sdp);\r\n } else {\r\n onAnswerData(payload.data.sdp);\r\n }\r\n } else if (service === 'Candidate') {\r\n // CreateAnswer 보다 candidate 이 먼저 응답이 오면 이 candidate은 버려진다.\r\n // 그래서 접속이 자꾸 실패함. candidate 에 대해 딜레이를 줬음. 나중에 더 나이스한 해결책이 필요함\r\n if (payload.data.channel_type === 'stream') {\r\n setTimeout(function () {\r\n onCandidateStream(payload.data.candidate.candidate);\r\n }, 1000);\r\n } else {\r\n setTimeout(function () {\r\n onCandidateData(payload.data.candidate.candidate);\r\n }, 1000);\r\n }\r\n } else if (service === 'Offer') {\r\n createAnswerData(payload.data.sdp, payload.data.label);\r\n }\r\n }\r\n };\r\n oncloseWS = () => {\r\n console.log('SWS', 'oncloseWS');\r\n };\r\n setupPeerConnection = () => {\r\n const thisComponent = this;\r\n const {iceServers} = this.props;\r\n const access_info = JSON.parse(sessionStorage.getItem('access_info'));\r\n let accessToken = '';\r\n let deviceAccessToken = '';\r\n if (access_info) {\r\n accessToken = access_info.access_token;\r\n deviceAccessToken = access_info.device_access_token\r\n }\r\n let ua = navigator.userAgent.toLowerCase();\r\n console.log(ua);\r\n if (ua.indexOf('safari') !== -1) {\r\n if (ua.indexOf('chrome') > -1) {\r\n // Chrome\r\n this.streamConnection = new RTCPeerConnection(iceServers)\r\n } else {\r\n // Safari\r\n this.streamConnection = new RTCPeerConnection({\r\n iceServers: [\r\n {\r\n \"urls\": \"stun:stun.l.google.com:19302\"\r\n }\r\n ]\r\n });\r\n }\r\n } else {\r\n this.streamConnection = new RTCPeerConnection(iceServers)\r\n }\r\n // console.log('SWS', 'stream', this.streamConnection);\r\n\r\n this.streamConnection.onclose = (e) => {\r\n console.log('streamConnection', 'onclose', e);\r\n };\r\n this.streamConnection.ontrack = (e) => {\r\n const base = document.getElementById('viewer-base');\r\n const video = document.getElementById('app-video');\r\n const thisComponent = this;\r\n if (video.srcObject !== e.streams[0]) {\r\n video.srcObject = e.streams[0];\r\n // console.log('received remote stream');\r\n video.addEventListener('loadedmetadata', function () {\r\n console.log(`Remote video videoWidth: ${this.videoWidth}px, videoHeight: ${this.videoHeight}px`);\r\n });\r\n video.onresize = () => {\r\n console.log(`Remote video size changed to ${video.videoWidth}x${video.videoHeight}`);\r\n // We'll use the first onsize callback as an indication that video has started\r\n // playing out.\r\n };\r\n video.addEventListener('mousedown', function (event) {\r\n const rect = video.getBoundingClientRect()\r\n const x = event.clientX - rect.left;\r\n const y = event.clientY - rect.top;\r\n // console.log(\"mousedown\", \"x: \" + x + \" y: \" + y);\r\n // console.log(\"width: \" + rect.width + \" height: \" + rect.height);\r\n if (event.button === 0) {\r\n const message = JSON.stringify({\r\n command: 'mouse_down',\r\n x: (x / rect.width) + '',\r\n y: (y / rect.height) + '',\r\n });\r\n // console.log(message);\r\n thisComponent.dataChannel.send(message);\r\n thisComponent.isMouseDown = true\r\n }\r\n });\r\n video.addEventListener('mouseup', function (event) {\r\n const rect = video.getBoundingClientRect()\r\n const x = event.clientX - rect.left;\r\n const y = event.clientY - rect.top;\r\n // console.log(\"mouseup\", \"x: \" + x + \" y: \" + y);\r\n // console.log(\"width: \" + rect.width + \" height: \" + rect.height);\r\n if (event.button === 0) {\r\n const message = JSON.stringify({\r\n command: 'mouse_up',\r\n x: (x / rect.width) + '',\r\n y: (y / rect.height) + '',\r\n });\r\n // console.log(message);\r\n thisComponent.dataChannel.send(message);\r\n }\r\n });\r\n video.addEventListener('mousemove', function (event) {\r\n const rect = video.getBoundingClientRect()\r\n const x = event.clientX - rect.left;\r\n const y = event.clientY - rect.top;\r\n if (thisComponent.isMouseDown) {\r\n const message = JSON.stringify({\r\n command: 'mouse_move',\r\n x: (x / rect.width) + '',\r\n y: (y / rect.height) + '',\r\n });\r\n // console.log(message);\r\n thisComponent.dataChannel.send(message);\r\n }\r\n // console.log(\"mousemove\", \"x: \" + x + \" y: \" + y);\r\n // console.log(\"width: \" + rect.width + \" height: \" + rect.height);\r\n });\r\n document.addEventListener('mouseup', function (event) {\r\n thisComponent.isMouseDown = false;\r\n })\r\n base.addEventListener('mousemove', function (event) {\r\n // console.log(\"fab mousemove:\", fab.style.top, fab.style.left, event.clientX, event.clientY);\r\n });\r\n }\r\n };\r\n this.streamConnection.onnegotiationneeded = () => {\r\n thisComponent.setState({\r\n isOpenedWebRTCRemote: true,\r\n });\r\n };\r\n this.streamConnection.onicecandidate = function (e) {\r\n // console.log('SWS', 'stream candidate', e);\r\n if (e.candidate) {\r\n const message = JSON.stringify({\r\n data: {\r\n category: 'ws',\r\n service: 'Candidate',\r\n access_token: accessToken,\r\n label: accessToken,\r\n opponent_dat: deviceAccessToken,\r\n channel_type: \"stream\",\r\n candidate: {\r\n type: 'candidate',\r\n candidate: e.candidate,\r\n },\r\n }\r\n });\r\n thisComponent.dataChannel.send(message);\r\n }\r\n };\r\n };\r\n createOfferStream = () => {\r\n const thisComponent = this;\r\n const {setupPeerConnection} = this;\r\n\r\n setupPeerConnection();\r\n\r\n const {streamConnection} = this;\r\n streamConnection.createOffer({\r\n offerToReceiveAudio: false, offerToReceiveVideo: true,\r\n }).then(function (offer) {\r\n const access_info = JSON.parse(sessionStorage.getItem('access_info'));\r\n let accessToken = '';\r\n let deviceAccessToken = '';\r\n if (access_info) {\r\n accessToken = access_info.access_token;\r\n deviceAccessToken = access_info.device_access_token\r\n }\r\n\r\n // console.log('thisComponent.opponentDAT', thisComponent.opponentDAT);\r\n const message = JSON.stringify({\r\n data: {\r\n category: 'ws',\r\n service: 'Offer',\r\n access_token: accessToken,\r\n channel_type: \"stream\",\r\n opponent_dat: deviceAccessToken,\r\n label: uuidv1(),\r\n sdp: offer,\r\n }\r\n });\r\n thisComponent.dataChannel.send(message);\r\n streamConnection.setLocalDescription(offer);\r\n }).catch(function (error) {\r\n console.log('SWS', 'An error has occurred.', error);\r\n });\r\n thisComponent.setState({\r\n isConnected: true,\r\n })\r\n };\r\n onAnswerStream = (answer) => {\r\n console.log('SWS', 'Answer', answer)\r\n this.streamConnection.setRemoteDescription(new RTCSessionDescription(answer));\r\n };\r\n onCandidateStream = (candidate) => {\r\n this.streamConnection.addIceCandidate(new RTCIceCandidate(candidate));\r\n };\r\n\r\n createAnswerData = (offer, label) => {\r\n const {iceServers} = this.props;\r\n const {onAnswerStream, onCandidateStream} = this;\r\n this.dataChannelLabel = label;\r\n let ua = navigator.userAgent.toLowerCase();\r\n console.log(ua);\r\n if (ua.indexOf('safari') !== -1) {\r\n if (ua.indexOf('chrome') > -1) {\r\n // Chrome\r\n console.log('SWS', 'Safari Test 1');\r\n this.dataConnection = new RTCPeerConnection(iceServers)\r\n } else {\r\n // Safari\r\n console.log('SWS', 'Safari Test 2');\r\n this.dataConnection = new RTCPeerConnection({\r\n iceServers: [\r\n {\r\n \"urls\": \"stun:stun.l.google.com:19302\"\r\n },\r\n {\r\n \"urls\": \"turn:turn.flowork.ai:3478?transport=udp\",\r\n \"username\": \"flowork\",\r\n \"credential\": \"Hotice1234!\"\r\n }\r\n ]\r\n });\r\n }\r\n } else {\r\n console.log('SWS', 'Safari Test 3');\r\n this.dataConnection = new RTCPeerConnection(iceServers)\r\n }\r\n\r\n console.log('SWS', this.dataConnection);\r\n\r\n const access_info = JSON.parse(sessionStorage.getItem('access_info'));\r\n let accessToken = '';\r\n let deviceAccessToken = '';\r\n if (access_info) {\r\n accessToken = access_info.access_token;\r\n deviceAccessToken = access_info.device_access_token\r\n }\r\n\r\n const thisComponent = this;\r\n const {createOfferStream} = this;\r\n\r\n // console.log(offer);\r\n // const d = JSON.parse(offer);\r\n thisComponent.dataConnection.setRemoteDescription(new RTCSessionDescription(offer));\r\n thisComponent.dataConnection.createAnswer(function (answer) {\r\n thisComponent.dataConnection.setLocalDescription(answer);\r\n let payload = {\r\n data: {\r\n category: 'ws',\r\n service: 'Answer',\r\n access_token: accessToken,\r\n opponent_dat: thisComponent.opponentDAT,\r\n label: thisComponent.dataChannelLabel,\r\n channel_type: \"data\",\r\n sdp: answer,\r\n }\r\n };\r\n thisComponent.sendWS(payload)\r\n }, function (error) {\r\n console.log('createAnswer', error);\r\n });\r\n thisComponent.dataConnection.oniceconnectionstatechange = e => {\r\n console.log('dataConnection oniceconnectionstatechange', e);\r\n };\r\n thisComponent.dataConnection.onicecandidate = function (e) {\r\n if (e.candidate) {\r\n thisComponent.sendWS({\r\n data: {\r\n category: 'ws',\r\n service: 'Candidate',\r\n access_token: accessToken,\r\n opponent_dat: thisComponent.opponentDAT,\r\n label: thisComponent.dataChannelLabel,\r\n channel_type: 'data',\r\n candidate: {\r\n type: 'candidate',\r\n candidate: e.candidate,\r\n },\r\n }\r\n });\r\n }\r\n };\r\n thisComponent.dataConnection.onnegotiationneeded = e => {\r\n console.log('onnegotiationneeded', e);\r\n };\r\n thisComponent.dataConnection.ondatachannel = (e) => {\r\n console.log('ondatachannel');\r\n thisComponent.dataChannel = e.channel;\r\n thisComponent.dataChannel.onclose = () => {\r\n console.log('remoteDataChannel has closed:', thisComponent.dataChannel.label);\r\n };\r\n thisComponent.dataChannel.onopen = () => {\r\n console.log('remoteDataChannel has opened:', thisComponent.dataChannel.label);\r\n thisComponent.setState({\r\n isOpenedDataChannel: true,\r\n });\r\n createOfferStream()\r\n };\r\n thisComponent.dataChannel.onmessage = e => {\r\n const payload = JSON.parse(e.data);\r\n console.log('remoteDataChannel onmessage', e.data);\r\n\r\n if (payload.data) {\r\n const service = payload.data.service;\r\n console.log('SWS', 'service', service);\r\n if (service === 'Answer') {\r\n if (payload.data.channel_type === 'stream') {\r\n onAnswerStream(payload.data.sdp);\r\n }\r\n } else if (service === 'Candidate') {\r\n if (payload.data.channel_type === 'stream') {\r\n setTimeout(function () {\r\n onCandidateStream(payload.data.candidate.candidate);\r\n }, 1000);\r\n }\r\n }\r\n }\r\n };\r\n }\r\n\r\n // dataConnection.createOffer()\r\n // .then(function (offer) {\r\n // // console.log('thisComponent.opponentDAT', thisComponent.opponentDAT);\r\n // let payload = {\r\n // data: {\r\n // category: 'ws',\r\n // service: 'Offer',\r\n // access_token: accessToken,\r\n // channel_type: \"data\",\r\n // opponent_dat: thisComponent.opponentDAT,\r\n // label: deviceAccessToken,\r\n // sdp: offer,\r\n // }\r\n // };\r\n // thisComponent.sendWS(payload);\r\n // dataConnection.setLocalDescription(offer);\r\n // }).catch(function (error) {\r\n // console.log('SWS', 'An error has occurred.', error);\r\n // });\r\n };\r\n onAnswerData = (answer) => {\r\n this.dataConnection.setRemoteDescription(new RTCSessionDescription(answer));\r\n };\r\n onCandidateData = (candidate) => {\r\n this.dataConnection.addIceCandidate(new RTCIceCandidate(candidate));\r\n };\r\n onClickPlayButton = () => {\r\n console.log('Play & Next');\r\n const message = JSON.stringify({\r\n command: 'switch',\r\n });\r\n this.dataChannel.send(message);\r\n };\r\n onClickHomeButton = () => {\r\n console.log('Home');\r\n const message = JSON.stringify({\r\n command: 'home',\r\n });\r\n this.dataChannel.send(message);\r\n };\r\n onClickBackButton = () => {\r\n console.log('Back');\r\n const message = JSON.stringify({\r\n command: 'back',\r\n });\r\n this.dataChannel.send(message);\r\n };\r\n onClickRecentButton = () => {\r\n console.log('Recent');\r\n const message = JSON.stringify({\r\n command: 'recent',\r\n });\r\n this.dataChannel.send(message);\r\n };\r\n\r\n componentDidMount() {\r\n console.log(this.props.device);\r\n this.opponentDAT = this.props.device.device_access_token\r\n }\r\n\r\n render() {\r\n const {isRequested, isConnected, isOpenedDataChannel} = this.state;\r\n const {onopenWS, onmessageWS, oncloseWS} = this;\r\n const {onClickPlayButton, onClickBackButton, onClickHomeButton, onClickRecentButton} = this;\r\n const {clearSelectedDevice} = this.props;\r\n return (\r\n \r\n {isConnected === false ?\r\n \r\n : null\r\n }\r\n\r\n {\r\n this.refWS = Websocket;\r\n }}/>\r\n
\r\n {isRequested ?\r\n
\r\n \r\n
\r\n :\r\n null\r\n }\r\n
\r\n
\r\n \r\n \r\n \r\n Pikabu Web\r\n \r\n\r\n
\r\n {isOpenedDataChannel ?\r\n \r\n \r\n \r\n : null\r\n }\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n )\r\n }\r\n\r\n}\r\n\r\nexport default StreamPage;\r\n","import React, {Component, Fragment} from 'react';\r\nimport List from '@material-ui/core/List';\r\nimport ListItem from '@material-ui/core/ListItem';\r\nimport ListItemText from '@material-ui/core/ListItemText';\r\nimport CustomLoader from \"../common/CustomLoader\";\r\nimport StreamPage from \"./StreamWebPage\";\r\nimport AppBar from \"@material-ui/core/AppBar/AppBar\";\r\nimport Toolbar from \"@material-ui/core/Toolbar\";\r\nimport Typography from \"@material-ui/core/Typography\";\r\nimport IconButton from \"@material-ui/core/IconButton\";\r\nimport PlayCircleFilledIcon from \"@material-ui/core/SvgIcon/SvgIcon\";\r\n\r\nclass MainPage extends Component {\r\n constructor(props) {\r\n super(props);\r\n };\r\n\r\n state = {\r\n isRequested: true,\r\n agentList: [],\r\n selectedDevice: null,\r\n iceServers: {},\r\n };\r\n\r\n GetAgentList = () => {\r\n const access_info = JSON.parse(sessionStorage.getItem('access_info'));\r\n let accessToken = '';\r\n if (access_info) {\r\n accessToken = access_info.access_token;\r\n }\r\n\r\n this.setState({\r\n isRequested: true,\r\n });\r\n fetch('/api/', {\r\n method: 'post',\r\n headers: {'Content-type': 'application/json'},\r\n body: JSON.stringify({\r\n data: {\r\n category: 'private',\r\n service: 'GetAgentList',\r\n access_token: accessToken,\r\n }\r\n })\r\n }).then(res => {\r\n if (res) {\r\n return res.json();\r\n }\r\n }).then(json => {\r\n if (!json) {\r\n return;\r\n }\r\n let agentList = [];\r\n if (json.data && json.data.agent_list) {\r\n agentList = json.data.agent_list\r\n }\r\n this.setState({\r\n isRequested: false,\r\n agentList: agentList,\r\n });\r\n }).catch(err => {\r\n console.log(err);\r\n });\r\n };\r\n\r\n GetSystemInformation = () => {\r\n const access_info = JSON.parse(sessionStorage.getItem('access_info'));\r\n let accessToken = '';\r\n if (access_info) {\r\n accessToken = access_info.access_token;\r\n }\r\n let send_data = {\r\n category: 'private',\r\n service: 'GetSystemInformation',\r\n access_token: accessToken,\r\n };\r\n\r\n fetch('/api/', {\r\n method: 'post',\r\n headers: {'Content-type': 'application/json'},\r\n body: JSON.stringify({\r\n \"data\": send_data\r\n })\r\n })\r\n .then(res => {\r\n console.log('service', res);\r\n if (res) {\r\n return res.json();\r\n }\r\n })\r\n .then(json => {\r\n if (!json) {\r\n return;\r\n }\r\n if (json.err) {\r\n console.log('service 실패', send_data.service, json);\r\n } else {\r\n console.log('service 성공', send_data.service, json);\r\n this.setState({\r\n iceServers: {\r\n iceServers: json.data.ice_servers\r\n },\r\n })\r\n }\r\n })\r\n .catch(err => {\r\n console.log(err);\r\n });\r\n };\r\n handleClickedListItem = (e, value) => {\r\n e.preventDefault();\r\n console.log('value:', value)\r\n this.setState({\r\n selectedDevice: value,\r\n })\r\n };\r\n clearSelectedDevice = () => {\r\n this.setState({\r\n selectedDevice: null,\r\n })\r\n };\r\n\r\n componentWillMount() {\r\n this.GetSystemInformation()\r\n }\r\n componentDidMount() {\r\n const {GetAgentList} = this;\r\n GetAgentList();\r\n }\r\n\r\n render() {\r\n const {isRequested, selectedDevice} = this.state;\r\n const {handleClickedListItem, clearSelectedDevice} = this;\r\n\r\n return (\r\n \r\n {isRequested ?\r\n \r\n : (selectedDevice ?\r\n \r\n :
\r\n \r\n \r\n \r\n My Computers\r\n \r\n \r\n \r\n \r\n {\r\n this.state.agentList.sort(function (a, b) {\r\n if ( a.name < b.name ){\r\n return -1;\r\n }\r\n if ( a.name > b.name ){\r\n return 1;\r\n }\r\n return 0;\r\n }).map(value => {\r\n return (\r\n {\r\n handleClickedListItem(e, value)\r\n }}\r\n />\r\n );\r\n })\r\n }\r\n \r\n
)\r\n\r\n }\r\n
\r\n )\r\n }\r\n\r\n}\r\n\r\nexport default MainPage;","import React, {Component, Fragment} from 'react';\r\nimport LoginPage from \"./LoginPage\";\r\nimport MainPage from \"./MainWebPage\";\r\n\r\nclass RemotePage extends Component {\r\n constructor(props) {\r\n super(props);\r\n };\r\n state = {\r\n isLogin: false,\r\n };\r\n\r\n componentDidMount() {\r\n }\r\n\r\n login = () => {\r\n this.setState({\r\n isLogin: true,\r\n })\r\n }\r\n\r\n logout = () => {\r\n this.setState({\r\n isLogin: false,\r\n })\r\n }\r\n render() {\r\n const { isLogin } = this.state\r\n const { login, logout } = this;\r\n return (\r\n \r\n {isLogin ?\r\n \r\n \r\n \r\n :\r\n \r\n \r\n \r\n }\r\n\r\n \r\n )\r\n }\r\n\r\n}\r\n\r\nexport default RemotePage;","import React, {Component, Fragment} from 'react';\r\n\r\nclass RemotePage extends Component {\r\n constructor(props) {\r\n super(props);\r\n };\r\n\r\n state = {\r\n connectionCount: 0,\r\n };\r\n\r\n componentDidMount() {\r\n const {requestGetConnection} = this;\r\n requestGetConnection()\r\n }\r\n\r\n requestGetConnection = () => {\r\n // const {requestGetConnection} = this;\r\n fetch('/api', {\r\n method: 'post',\r\n headers: {'Content-type': 'application/json'},\r\n body: JSON.stringify({\r\n \"data\": {\r\n category: 'private',\r\n service: 'GetConnections',\r\n access_token: '34a514e8dc0e11e9a29d02420aff012a',\r\n }\r\n })\r\n })\r\n .then(res => res.json())\r\n .then(json => {\r\n if (json.data) {\r\n let connectionCount = 0;\r\n let todayNewUserCount = 0;\r\n let androidConnectionCount = 0;\r\n let iosConnectionCount = 0;\r\n let agentConnectionCount = 0;\r\n if (json.data.connection_number) {\r\n connectionCount = json.data.connection_number;\r\n }\r\n if (json.data.today_new_user_count) {\r\n todayNewUserCount = json.data.today_new_user_count;\r\n }\r\n if (json.data.android_connection_count) {\r\n androidConnectionCount = json.data.android_connection_count;\r\n }\r\n if (json.data.ios_connection_count) {\r\n iosConnectionCount = json.data.ios_connection_count;\r\n }\r\n if (json.data.agent_connection_count) {\r\n agentConnectionCount = json.data.agent_connection_count;\r\n }\r\n this.setState({\r\n connectionCount: connectionCount,\r\n todayNewUserCount: todayNewUserCount,\r\n androidConnectionCount: androidConnectionCount,\r\n iosConnectionCount: iosConnectionCount,\r\n agentConnectionCount: agentConnectionCount,\r\n })\r\n // setTimeout(function () {\r\n // requestGetConnection()\r\n // }, 3000)\r\n\r\n }\r\n })\r\n .catch(err => console.log(err));\r\n };\r\n reload = () => {\r\n // window.location.reload();\r\n this.requestGetConnection()\r\n };\r\n\r\n render() {\r\n const {connectionCount, todayNewUserCount, androidConnectionCount, iosConnectionCount, agentConnectionCount} = this.state;\r\n return (\r\n \r\n
\r\n
{this.reload(e)}}>\r\n
현재 접속자
\r\n
{connectionCount}
\r\n
신규
\r\n
{todayNewUserCount}
\r\n
iOS
\r\n
{iosConnectionCount}
\r\n
안드로이드
\r\n
{androidConnectionCount}
\r\n
PC
\r\n
{agentConnectionCount}
\r\n
\r\n
\r\n
\r\n )\r\n }\r\n\r\n}\r\n\r\nexport default RemotePage;\r\n","import React from 'react';\r\nimport classNames from 'classnames';\r\n\r\nimport './AbstractIcon.scss';\r\n\r\nconst CircleCompleteIcon = ({ classes, size = 'md' }) => {\r\n return (\r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\nexport default CircleCompleteIcon;\r\n","import React from 'react';\r\nimport classNames from 'classnames';\r\n\r\nimport './AbstractIcon.scss';\r\n\r\nconst CircleFailIcon = ({classes, size = 'md'}) => {\r\n return (\r\n \r\n \r\n \r\n\r\n );\r\n};\r\n\r\nexport default CircleFailIcon;\r\n","import React, {useState} from 'react';\r\nimport './SNSLogin.scss';\r\nimport Button from \"@material-ui/core/Button\";\r\nimport {useHistory} from 'react-router-dom';\r\nimport axios from 'axios';\r\nimport CircleCompleteIcon from \"../components/atom/icons/CircleCompleteIcon\";\r\nimport CircleFailIcon from \"../components/atom/icons/CircleFailIcon\";\r\n\r\nexport default function SNSLogin(props) {\r\n\r\n console.log(props);\r\n const { success } = props;\r\n\r\n return (\r\n
\r\n {success === \"success\" ?\r\n <>\r\n
\r\n \r\n
\r\n
\r\n 로그인에 성공했습니다.\r\n
\r\n :\r\n <>\r\n
\r\n \r\n
\r\n
\r\n 로그인에 실패했습니다.\r\n
\r\n \r\n }\r\n {\r\n window.location.href = 'https://pikaburemote.page.link/6SuK';\r\n }}\r\n >\r\n 확인\r\n \r\n
\r\n )\r\n}\r\n","import React, {Component} from 'react';\r\nimport './App.css';\r\nimport {\r\n DownloadPage,\r\n RemotePage,\r\n RemoteWebPage,\r\n DashboardPage,\r\n SNSLogin,\r\n} from './pages';\r\nimport { Route, Switch, useLocation } from 'react-router-dom';\r\n\r\nconst App = () => {\r\n\r\n const query = new URLSearchParams(useLocation().search);\r\n const command = query.get(\"command\");\r\n const param = query.get(\"param\");\r\n\r\n console.log('command', command, 'param', param);\r\n\r\n switch(command) {\r\n case 'download':\r\n return ;\r\n case 'remote':\r\n return ;\r\n case 'web':\r\n return ;\r\n case 'dashboard':\r\n return ;\r\n case 'oauth':\r\n return ;\r\n default:\r\n return
Not found
\r\n }\r\n\r\n};\r\nexport default App;\r\n","// This optional code is used to register a service worker.\r\n// register() is not called by default.\r\n\r\n// This lets the app load faster on subsequent visits in production, and gives\r\n// it offline capabilities. However, it also means that developers (and users)\r\n// will only see deployed updates on subsequent visits to a pages, after all the\r\n// existing tabs open on the pages have been closed, since previously cached\r\n// resources are updated in the background.\r\n\r\n// To learn more about the benefits of this model and instructions on how to\r\n// opt-in, read https://bit.ly/CRA-PWA\r\n\r\nconst isLocalhost = Boolean(\r\n window.location.hostname === 'localhost' ||\r\n // [::1] is the IPv6 localhost address.\r\n window.location.hostname === '[::1]' ||\r\n // 127.0.0.1/8 is considered localhost for IPv4.\r\n window.location.hostname.match(\r\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\r\n )\r\n);\r\n\r\nexport function register(config) {\r\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\r\n // The URL constructor is available in all browsers that support SW.\r\n const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);\r\n if (publicUrl.origin !== window.location.origin) {\r\n // Our service worker won't work if PUBLIC_URL is on a different origin\r\n // from what our pages is served on. This might happen if a CDN is used to\r\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\r\n return;\r\n }\r\n\r\n window.addEventListener('load', () => {\r\n const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\r\n\r\n if (isLocalhost) {\r\n // This is running on localhost. Let's check if a service worker still exists or not.\r\n checkValidServiceWorker(swUrl, config);\r\n\r\n // Add some additional logging to localhost, pointing developers to the\r\n // service worker/PWA documentation.\r\n navigator.serviceWorker.ready.then(() => {\r\n console.log(\r\n 'This web app is being served cache-first by a service ' +\r\n 'worker. To learn more, visit https://bit.ly/CRA-PWA'\r\n );\r\n });\r\n } else {\r\n // Is not localhost. Just register service worker\r\n registerValidSW(swUrl, config);\r\n }\r\n });\r\n }\r\n}\r\n\r\nfunction registerValidSW(swUrl, config) {\r\n navigator.serviceWorker\r\n .register(swUrl)\r\n .then(registration => {\r\n registration.onupdatefound = () => {\r\n const installingWorker = registration.installing;\r\n if (installingWorker == null) {\r\n return;\r\n }\r\n installingWorker.onstatechange = () => {\r\n if (installingWorker.state === 'installed') {\r\n if (navigator.serviceWorker.controller) {\r\n // At this point, the updated precached content has been fetched,\r\n // but the previous service worker will still serve the older\r\n // content until all client tabs are closed.\r\n console.log(\r\n 'New content is available and will be used when all ' +\r\n 'tabs for this pages are closed. See https://bit.ly/CRA-PWA.'\r\n );\r\n\r\n // Execute callback\r\n if (config && config.onUpdate) {\r\n config.onUpdate(registration);\r\n }\r\n } else {\r\n // At this point, everything has been precached.\r\n // It's the perfect time to display a\r\n // \"Content is cached for offline use.\" message.\r\n console.log('Content is cached for offline use.');\r\n\r\n // Execute callback\r\n if (config && config.onSuccess) {\r\n config.onSuccess(registration);\r\n }\r\n }\r\n }\r\n };\r\n };\r\n })\r\n .catch(error => {\r\n console.error('Error during service worker registration:', error);\r\n });\r\n}\r\n\r\nfunction checkValidServiceWorker(swUrl, config) {\r\n // Check if the service worker can be found. If it can't reload the pages.\r\n fetch(swUrl)\r\n .then(response => {\r\n // Ensure service worker exists, and that we really are getting a JS file.\r\n const contentType = response.headers.get('content-type');\r\n if (\r\n response.status === 404 ||\r\n (contentType != null && contentType.indexOf('javascript') === -1)\r\n ) {\r\n // No service worker found. Probably a different app. Reload the pages.\r\n navigator.serviceWorker.ready.then(registration => {\r\n registration.unregister().then(() => {\r\n window.location.reload();\r\n });\r\n });\r\n } else {\r\n // Service worker found. Proceed as normal.\r\n registerValidSW(swUrl, config);\r\n }\r\n })\r\n .catch(() => {\r\n console.log(\r\n 'No internet connection found. App is running in offline mode.'\r\n );\r\n });\r\n}\r\n\r\nexport function unregister() {\r\n if ('serviceWorker' in navigator) {\r\n navigator.serviceWorker.ready.then(registration => {\r\n registration.unregister();\r\n });\r\n }\r\n}\r\n","import React from 'react';\r\nimport ReactDOM from 'react-dom';\r\nimport './index.css';\r\nimport App from './App';\r\nimport * as serviceWorker from './serviceWorker';\r\nimport {\r\n BrowserRouter as Router,\r\n} from \"react-router-dom\";\r\n\r\nReactDOM.render(\r\n \r\n \r\n \r\n \r\n \r\n\r\n ,\r\n document.getElementById('root')\r\n);\r\n\r\n// If you want your app to work offline and load faster, you can change\r\n// unregister() to register() below. Note this comes with some pitfalls.\r\n// Learn more about service workers: https://bit.ly/CRA-PWA\r\nserviceWorker.unregister();\r\n"],"sourceRoot":""}