Пишу код для веб-чата.
Описал серверную часть, но не работает верстка на реакте.
Суть такая - мне нужно ввести имя, и скопировать id конференции(с этим и проблема, id не копируется). Скинуть id другу и он подключается к конференции.
Не работает процесс извлечения id, и звонка другому пользователю
import Button from "@material-ui/core/Button"
import IconButton from "@material-ui/core/IconButton"
import TextField from "@material-ui/core/TextField"
import AssignmentIcon from "@material-ui/icons/Assignment"
import PhoneIcon from "@material-ui/icons/Phone"
import React, {useEffect, useRef, useState} from "react"
import {CopyToClipboard} from "react-copy-to-clipboard"
import Peer from "simple-peer"
import io from "socket.io-client"
import "./App.css"
//connected socket to out host
const socket = io.connect('http://localhost:5000')
function App() {
//states with hooks
const [me, setMe] = useState("")
const [stream, setStream] = useState()
const [receivingCall, setReceivingCall] = useState(false)
const [caller, setCaller] = useState()
const [callerSignal, setCallerSignal] = useState()
const [callAccepted, setCallAccepted] = useState(false)
const [idToCall, setIdToCall] = useState("")
const [callEnded, setCallEnded] = useState(false)
const [name, setName] = useState("")
//refs, catch current state of param
const myVideo = useRef()
const userVideo = useRef()
const connectionRef = useRef()
//use useEffect to drop Classes, and make code more simple
useEffect(() => {
//set input device parameters
navigator.mediaDevices.getUserMedia({
video: true, audio: true
}).then((stream)=>{
//change stream state
setStream(stream)
//set ref of my video to the comming stream
myVideo.current.srcObject = stream
})
//client side event handling
socket.on('me', (id)=>{
setMe(id)
})
socket.on('callUser', (data)=>{
setReceivingCall(true)
setCaller(data.from)
setName(data.name)
setCallerSignal(data.signal)
})
}, []);
//call event handler
const callUser = (id) => {
const peer = new Peer({
initializer : true,
trickle : false,
stream : stream
})
//catch a signal event
peer.on('signal', data=>{
console.log('data' , data)
console.log('id' ,id)
socket.emit('callUser', {
userToCall : id,
signalData : data,
from : me,
name : name
})
})
peer.on('stream', (stream)=>{
userVideo.current.srcObject = stream
})
socket.on('callAccepted', (signal)=>{
setCallAccepted(true)
peer.signal(signal)
})
connectionRef.current = peer
console.log(connectionRef.current)
}
//answer call event handler
const answerCall = () =>{
setCallAccepted(true)
const peer = new Peer({
initializer : false,
trickle : false,
stream : stream
})
peer.on('signal', (data)=>{
socket.emit('answerCall', {
signal : data,
to : caller
})
})
peer.on('stream', (stream)=>{
userVideo.current.srcObject = stream
})
peer.signal(callerSignal)
connectionRef.current = peer
console.log(connectionRef.current)
}
const leaveCall = () =>{
setCallEnded(true)
connectionRef.current.destroy()
}
return (
<>
<h1 style={{ textAlign: "center", color: '#fff' }}>Simple Video Chat</h1>
<div className="container">
<div className="video-container">
<div className="video">
{stream && <video playsInline muted ref={myVideo} autoPlay style={{ width: "300px" }} />}
</div>
<div className="video">
{callAccepted && !callEnded ?
<video playsInline ref={userVideo} autoPlay style={{ width: "300px"}} />:
null}
</div>
</div>
<div className="myId">
<TextField
id="filled-basic"
label="Name"
variant="filled"
value={name}
onChange={(e) => setName(e.target.value)}
style={{ marginBottom: "20px" }}
/>
<CopyToClipboard text={idToCall} style={{ marginBottom: "2rem" }}>
<Button variant="contained" color="primary" startIcon={<AssignmentIcon fontSize="large" />}>
Copy ID
</Button>
</CopyToClipboard>
<TextField
id="filled-basic"
label="ID to call"
variant="filled"
value={idToCall}
onChange={(e) => setIdToCall(e.target.value)}
/>
<div className="call-button">
{callAccepted && !callEnded ? (
<Button variant="contained" color="secondary" onClick={leaveCall}>
End Call
</Button>
) : (
<IconButton color="primary" aria-label="call" onClick={() => callUser(idToCall)}>
<PhoneIcon fontSize="large" />
</IconButton>
)}
{idToCall}
</div>
</div>
<div>
{receivingCall && !callAccepted ? (
<div className="caller">
<h1 >{name} is calling...</h1>
<Button variant="contained" color="primary" onClick={answerCall}>
Answer
</Button>
</div>
) : true}
</div>
</div>
</>
);
}
export default App;