|
@@ -16,10 +16,11 @@ import VideocamOffIcon from '@mui/icons-material/VideocamOff';
|
|
|
import MicIcon from '@mui/icons-material/Mic';
|
|
|
import MicOffIcon from '@mui/icons-material/MicOff';
|
|
|
import CallEndIcon from '@mui/icons-material/CallEnd';
|
|
|
-
|
|
|
+import Alert from '@mui/material/Alert';
|
|
|
+
|
|
|
import { getChat } from '../../../redux/chat/selector';
|
|
|
import { getAuthorizationState } from '../../../redux/authorization/selector';
|
|
|
-import { prodAwsS3,prodSocketURL, firstLetter, slicedWord,getTimeBySeconds } from '../../../helpers'
|
|
|
+import { prodAwsS3,prodBaseURL,prodSocketURL, firstLetter, slicedWord,getTimeBySeconds,playNotification,playNotificationWithoutPermission } from '../../../helpers'
|
|
|
import { socketIdChat } from '../../../api-data';
|
|
|
|
|
|
const Peer = require('simple-peer')
|
|
@@ -69,7 +70,8 @@ const useStyles = makeStyles({
|
|
|
rightIconWrapperClose: {
|
|
|
color: '#ffffff',
|
|
|
cursor: 'pointer',
|
|
|
- padding:'3px 10px 3px 10px',
|
|
|
+ padding: '3px 10px 3px 10px',
|
|
|
+ backgroundColor:'rgb(36, 36, 36)',
|
|
|
borderTopRightRadius:7,
|
|
|
'&:hover': {
|
|
|
backgroundColor:'#f02a2a'
|
|
@@ -121,8 +123,6 @@ const useStyles = makeStyles({
|
|
|
paddingTop:7
|
|
|
},
|
|
|
myVideo: {
|
|
|
- width: 250,
|
|
|
- height: 'auto',
|
|
|
cursor: 'pointer',
|
|
|
position: 'absolute',
|
|
|
top: 0,
|
|
@@ -162,6 +162,7 @@ const CallBar = ({callStatus,setCallStatus}:ICallBar) => {
|
|
|
const myVideoRef = useRef<any>(null);
|
|
|
const companionVideoRef = useRef<any>(null);
|
|
|
const companionAudioRef = useRef<any>(null);
|
|
|
+ const [audioRing,setAudioRing] = useState<any>(null)
|
|
|
const [mutedMyVideo,setMutedMyVideo] = useState<boolean>(false)
|
|
|
const [mutedMyAudio,setMutedMyAudio] = useState<boolean>(false)
|
|
|
const [mySocket, setMySocket] = useState<string>('')
|
|
@@ -175,23 +176,30 @@ const CallBar = ({callStatus,setCallStatus}:ICallBar) => {
|
|
|
const [number, setNumber] = useState<string>('')
|
|
|
const [conversationLast, cetConversationLast] = useState<string>('')
|
|
|
const [fullScreen, setFullScreen] = useState<boolean>(false)
|
|
|
+ const [alert, setAlert] = useState<string>('')
|
|
|
const handleConversationLast = (e: any) =>
|
|
|
cetConversationLast(getTimeBySeconds(e.target.currentTime))
|
|
|
const handleMuteVideo = () => {
|
|
|
if (myStream&&myStream.getVideoTracks()[0]) {
|
|
|
setMutedMyVideo(!mutedMyVideo)
|
|
|
myStream.getVideoTracks()[0].enabled = !myStream.getVideoTracks()[0].enabled
|
|
|
+ } else {
|
|
|
+ setAlert(`You can not ${mutedMyVideo?'enable':'disable'} Video before stream started`)
|
|
|
}
|
|
|
}
|
|
|
const handleMuteAudio = () => {
|
|
|
if (myStream&&myStream.getAudioTracks()[0]) {
|
|
|
setMutedMyAudio(!mutedMyAudio)
|
|
|
myStream.getAudioTracks()[0].enabled = !myStream.getAudioTracks()[0].enabled
|
|
|
+ } else {
|
|
|
+ setAlert(`You can not ${mutedMyAudio?'enable':'disable'} Audio before stream started`)
|
|
|
}
|
|
|
}
|
|
|
const handleLeaveCall = () => {
|
|
|
setCallStatus('hanging up...')
|
|
|
- connectionRef.current.destroy();
|
|
|
+ if (connectionRef.current) {
|
|
|
+ connectionRef.current.destroy();
|
|
|
+ }
|
|
|
setCallStatus('')
|
|
|
};
|
|
|
const handleStartCall = useCallback(async () => {
|
|
@@ -209,6 +217,8 @@ const CallBar = ({callStatus,setCallStatus}:ICallBar) => {
|
|
|
stream
|
|
|
});
|
|
|
setCallStatus('ringing...')
|
|
|
+ setAlert('')
|
|
|
+ setAudioRing(playNotification(`${prodBaseURL}/calling.mp3`))
|
|
|
peer.on("signal", (data: any) => {
|
|
|
socket.emit("callTo", {
|
|
|
to: socketId,
|
|
@@ -222,20 +232,18 @@ const CallBar = ({callStatus,setCallStatus}:ICallBar) => {
|
|
|
companionVideoRef.current.srcObject = companionStream;
|
|
|
companionAudioRef.current.srcObject = companionStream;
|
|
|
});
|
|
|
- peer.on('error', (e: any) => console.log('error from peer', e))
|
|
|
- peer.on('connect', () => {
|
|
|
- console.log('CONNECT')
|
|
|
- })
|
|
|
socket.on("acceptedCall", ({ signal }: any) => {
|
|
|
setCallStatus('connection')
|
|
|
+ audioRing.pause()
|
|
|
peer.signal(signal)
|
|
|
setCallStatus('conversation')
|
|
|
});
|
|
|
connectionRef.current = peer;
|
|
|
- },[socketId,companionId,_id,mySocket,myVideoRef,setCallStatus])
|
|
|
+ },[socketId,companionId,_id,mySocket,myVideoRef,setCallStatus,audioRing])
|
|
|
|
|
|
const handleAnswerCall = useCallback(async () => {
|
|
|
setCallStatus('connection')
|
|
|
+ audioRing.pause()
|
|
|
const stream = await navigator.mediaDevices.getUserMedia({
|
|
|
video: true,
|
|
|
audio: true
|
|
@@ -253,6 +261,7 @@ const CallBar = ({callStatus,setCallStatus}:ICallBar) => {
|
|
|
to: companionSocket,
|
|
|
});
|
|
|
setCallStatus('conversation')
|
|
|
+ setAlert('')
|
|
|
});
|
|
|
peer.on("stream", (companionStream: any) => {
|
|
|
companionVideoRef.current.srcObject = companionStream;
|
|
@@ -260,7 +269,7 @@ const CallBar = ({callStatus,setCallStatus}:ICallBar) => {
|
|
|
});
|
|
|
peer.signal(companionSignal);
|
|
|
connectionRef.current = peer;
|
|
|
- },[companionSocket,companionSignal,setCallStatus])
|
|
|
+ },[companionSocket,companionSignal,setCallStatus,audioRing])
|
|
|
|
|
|
useEffect(() => {
|
|
|
socket.on("me", (id: string) => {
|
|
@@ -277,6 +286,7 @@ const CallBar = ({callStatus,setCallStatus}:ICallBar) => {
|
|
|
setNumber(number)
|
|
|
setCompanionSocket(from)
|
|
|
setCompanionSignal(signal)
|
|
|
+ setAudioRing(playNotificationWithoutPermission(`${prodBaseURL}/ringing.mp3`))
|
|
|
}
|
|
|
})
|
|
|
}, [setCallStatus])
|
|
@@ -297,7 +307,8 @@ const CallBar = ({callStatus,setCallStatus}:ICallBar) => {
|
|
|
|
|
|
return (
|
|
|
<div className={classes.container} style={{ top: callStatus ? 0 : '-100%'}}>
|
|
|
- <video className={classes.myVideo} ref={myVideoRef} playsInline autoPlay muted controls={false}/>
|
|
|
+ <video className={classes.myVideo} style={{width: !myStream || mutedMyVideo?0:250,height: !myStream || mutedMyVideo?0:'auto'}}
|
|
|
+ ref={myVideoRef} playsInline autoPlay muted controls={false} />
|
|
|
<Moveable
|
|
|
target={myVideoRef.current}
|
|
|
draggable={true}
|
|
@@ -312,31 +323,37 @@ const CallBar = ({callStatus,setCallStatus}:ICallBar) => {
|
|
|
<div className={classes.modalCall} style={{width: fullScreen?'100vw':'34vw',height:fullScreen?'100vh':'auto'}}>
|
|
|
<div className={classes.rightIcons}>
|
|
|
<div className={classes.rightIconWrapper} onClick={() => setFullScreen(false)}
|
|
|
- style={{backgroundColor:fullScreen?'transparent':'rgb(70, 70, 70)'}}>
|
|
|
+ style={{backgroundColor:fullScreen?'rgb(36, 36, 36)':'rgb(70, 70, 70)'}}>
|
|
|
<MinimizeIcon fontSize='small' />
|
|
|
</div>
|
|
|
<div className={classes.rightIconWrapper} onClick={() => setFullScreen(true)}
|
|
|
- style={{backgroundColor:fullScreen?'rgb(70, 70, 70)':'transparent'}}>
|
|
|
+ style={{backgroundColor:fullScreen?'rgb(70, 70, 70)':'rgb(36, 36, 36)'}}>
|
|
|
<CropLandscapeIcon fontSize='small' />
|
|
|
</div>
|
|
|
<div className={classes.rightIconWrapperClose} onClick={handleLeaveCall}>
|
|
|
<CloseIcon fontSize='small' />
|
|
|
</div>
|
|
|
</div>
|
|
|
- {callStatus !== 'conversation'&&<ListItemAvatar style={{margin:'25px 0px 5px 0px'}}>
|
|
|
- <Avatar alt={name} src={avatarUrl?`${prodAwsS3}/${avatarUrl}`:undefined}
|
|
|
- sx={{ background: color, width: 120, height: 120, marginRight: 2, fontSize:30,zIndex:0}}>
|
|
|
- {`${firstLetter(name)}${firstLetter(lastName)}`}
|
|
|
- </Avatar>
|
|
|
- </ListItemAvatar>}
|
|
|
- {/* <ListItemText primary={`${firstLetter(name)}${slicedWord(name, 15, 1)}
|
|
|
- ${firstLetter(lastName)}${slicedWord(lastName, 15, 1)}`}
|
|
|
- primaryTypographyProps={{ color: '#dfdfdf', fontSize: 20, fontWeight: 500 }}/>
|
|
|
- <ListItemText primary={number} primaryTypographyProps={{ color: '#ffffff', fontSize: 15, fontWeight: 500, textAlign: "center" }} />
|
|
|
- <ListItemText secondary={callStatus} secondaryTypographyProps={{ color: "#dfdfdf", textAlign: "center" }} />
|
|
|
- <ListItemText secondary={conversationLast} secondaryTypographyProps={{ color: "#dfdfdf", textAlign: "center" }} /> */}
|
|
|
+ <div style={{ width: '100%', position: "relative" }}>
|
|
|
+ {alert && <Alert variant="filled" severity="info" sx={{ backgroundColor: "rgb(70, 70, 70)" }}
|
|
|
+ style={{ width: fullScreen?'auto':"100%", position: 'absolute', left: 0, bottom: -48 }}>{alert}</Alert>}
|
|
|
+ {!fullScreen && <>
|
|
|
+ <ListItemAvatar style={{margin:'25px 0px 5px 0px'}}>
|
|
|
+ <Avatar alt={name} src={avatarUrl?`${prodAwsS3}/${avatarUrl}`:undefined}
|
|
|
+ sx={{ background: color, width: 120, height: 120, marginRight: 2, fontSize:30,zIndex:0,margin:'0 auto'}}>
|
|
|
+ {`${firstLetter(name)}${firstLetter(lastName)}`}
|
|
|
+ </Avatar>
|
|
|
+ </ListItemAvatar>
|
|
|
+ <ListItemText primary={`${firstLetter(name)}${slicedWord(name, 15, 1)}
|
|
|
+ ${firstLetter(lastName)}${slicedWord(lastName, 15, 1)}`}
|
|
|
+ primaryTypographyProps={{ color: '#dfdfdf', fontSize: 20, fontWeight: 500,textAlign: "center" }}/>
|
|
|
+ <ListItemText primary={number} primaryTypographyProps={{ color: '#ffffff', fontSize: 15, fontWeight: 500, textAlign: "center" }} />
|
|
|
+ <ListItemText secondary={callStatus} secondaryTypographyProps={{ color: "#dfdfdf", textAlign: "center" }} />
|
|
|
+ <ListItemText secondary={conversationLast} secondaryTypographyProps={{ color: "#dfdfdf", textAlign: "center" }} />
|
|
|
+ </>}
|
|
|
+ </div>
|
|
|
<video ref={companionVideoRef} playsInline muted autoPlay controls={false}
|
|
|
- style={{width: '100%',height:fullScreen?'100vh': 'auto',objectFit: 'cover'}} onTimeUpdate={handleConversationLast} />
|
|
|
+ style={{width: '100%',height:fullScreen?'100vh': 'auto',objectFit: 'cover',backgroundColor:'rgb(36, 36, 36)'}} onTimeUpdate={handleConversationLast} />
|
|
|
<audio ref={companionAudioRef} autoPlay />
|
|
|
<div className={classes.bottomWrapper}>
|
|
|
<div className={classes.bottomItem} onClick={handleMuteVideo}>
|