123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 |
- import { makeStyles, Typography } from '@material-ui/core'
- import { useState,useEffect } from 'react';
- import { useSelector } from 'react-redux';
- import ListItemText from '@mui/material/ListItemText';
- import ListItemAvatar from '@mui/material/ListItemAvatar';
- import Avatar from '@mui/material/Avatar';
- import MinimizeIcon from '@mui/icons-material/Minimize';
- import CropLandscapeIcon from '@mui/icons-material/CropLandscape';
- import CloseIcon from '@mui/icons-material/Close';
- import ScreenShareIcon from '@mui/icons-material/ScreenShare';
- import StopScreenShareIcon from '@mui/icons-material/StopScreenShare';
- import VideocamIcon from '@mui/icons-material/Videocam';
- 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 Moveable from "react-moveable";
- import { OnDrag } from "react-moveable";
- import { getChat } from '../../../../../../redux/chat/selector';
- import { prodAwsS3,firstLetter,slicedWord } from '../../../../../../helpers'
- const useStyles = makeStyles({
- overlay: {
- position: 'fixed',
- top: 0,
- left: 0,
- width: '100vw',
- height: '100vh',
- zIndex: 100,
- overflow: 'hidden',
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center',
- alignContent: "center",
- backgroundColor: 'rgba(104, 105, 104, 0.6)',
- },
- shareScreenActive: {
- width: '90%',
- borderRadius: 7,
- margin: 'auto',
- border:'solid 2px #0084ff',
- },
- shareScreenDisabled: {
- width: 0,
- height:0,
- },
- modalCall: {
- background: 'rgb(36, 36, 36)',
- display: 'flex',
- flexDirection: 'column',
- justifyContent: 'start',
- alignItems: 'center',
- justifyItems:"center",
- width: '34vw',
- height:'50vh',
- borderRadius: 7,
- },
- rightIcons: {
- display: 'flex',
- justifyContent: 'end',
- alignContent: 'center',
- alignItems: 'center',
- width:'100%'
- },
- rightIconWrapper: {
- color: '#ffffff',
- cursor: 'pointer',
- padding:'3px 10px 3px 10px',
- '&:hover': {
- backgroundColor:'rgb(80, 80, 80)'
- }
- },
- rightIconWrapperClose: {
- color: '#ffffff',
- cursor: 'pointer',
- padding:'3px 10px 3px 10px',
- borderTopRightRadius:7,
- '&:hover': {
- backgroundColor:'#f02a2a'
- }
- },
- statusCall: {
- color: "#dfdfdf",
- animation: 'ripple 4s infinite ease-in-out',
- },
- animatedDots: {
- fontWeight: 'bold',
- display:'inline-block',
- fontFamily: 'monospace',
- clipPath: 'inset(0 3ch 0 0)',
- animation: `$run 2s steps(5) infinite`,
- },
- bottomWrapper: {
- display: 'flex',
- justifyContent: 'center',
- padding: 5
- },
- bottomItem: {
- display: 'flex',
- flexDirection: 'column',
- justifyContent: 'center',
- alignContent: 'center',
- alignItems: 'center',
- cursor:'pointer',
- width: 80,
- },
- bottomIcon: {
- cursor:'pointer',
- },
- titleIconBottom: {
- color: '#ffffff',
- fontSize: 13,
- paddingTop:7
- },
- '@keyframes run': {
- to: {
- clipPath: 'inset(0 -1ch 0 0)'
- },
- },
- })
- interface ICallModal {
- setModalCall:any,
- shareRef: any,
- videoRef: any,
- }
- const CallModal = ({setModalCall,shareRef,videoRef}:ICallModal) => {
- const classes = useStyles()
- const { name, lastName, avatarUrl, color } = useSelector(getChat)
- const [audio, setAudio] = useState<boolean>(true)
- const [video, setVideo] = useState<any>(false)
- const [share, setShare] = useState<any>(null)
- const handleShareScreen = async () => {
- const displayMediaStreamConstraints = {
- video: true,
- };
- const navigator:any = window.navigator
- const stream = await navigator.mediaDevices.getDisplayMedia(displayMediaStreamConstraints);
- shareRef.current.srcObject = stream;
- setShare(true)
- stream.getVideoTracks()[0].onended = () => setShare(false)
- };
- const handleAudio = () => setAudio(prevState => !prevState)
- const handleVideo = async () => {
- const displayMediaStreamConstraints = {
- audio: false,
- video: {
- width: {
- min: 1280,
- ideal: 1920,
- max: 2560,
- },
- height: {
- min: 720,
- ideal: 1080,
- max: 1440
- },
- facingMode: 'user'
- },
- };
- const navigator:any = window.navigator
- const stream = await navigator.mediaDevices.getUserMedia(displayMediaStreamConstraints)
-
- if (!video) {
- setVideo(true)
- videoRef.current.srcObject = stream;
- } else {
- videoRef.current.srcObject = null;
- stream.getVideoTracks()[0].stop()
- setVideo(false)
- }
- }
- const handleCloseCallModal = () => setModalCall(false)
- // requesting, waiting ,ringing, hanging up,line busy
- // useEffect(() => {
- // socket.on('connect', () => {
- // setIsConnected(true);
- // });
- // socket.on('disconnect', () => {
- // setIsConnected(false);
- // });
- // socket.on('pong', () => {
- // setLastPong(new Date().toISOString());
- // });
- // return () => {
- // socket.off('connect');
- // socket.off('disconnect');
- // socket.off('pong');
- // };
- // }, []);
- return (
- <div className={classes.overlay} >
- <video ref={videoRef} style={{width: video ? 250 : 0, height: video ? 'auto' : 0, cursor: 'pointer',
- position: 'absolute', top: 0, left: 0, zIndex: 100}} playsInline autoPlay muted/>
- <Moveable
- target={videoRef.current}
- draggable={true}
- throttleDrag={0}
- hideDefaultLines={true}
- renderDirections={[]}
- rotationPosition="none"
- origin={false}
- onDrag={({ target, transform }: OnDrag) =>
- target!.style.transform = transform }
- />
- <div className={classes.modalCall}>
- <div className={classes.rightIcons} style={{marginBottom: share?0:40,}}>
- <div className={classes.rightIconWrapper}>
- <MinimizeIcon fontSize='small' />
- </div>
- <div className={classes.rightIconWrapper}>
- <CropLandscapeIcon fontSize='small' />
- </div>
- <div className={classes.rightIconWrapperClose} onClick={handleCloseCallModal}>
- <CloseIcon fontSize='small' />
- </div>
- </div>
- {!share&&<ListItemAvatar style={{marginBottom:15}}>
- <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>}
- {!share&&<div style={{marginBottom:'auto'}}>
- <ListItemText primary={`${firstLetter(name)}${slicedWord(name, 15, 1)}
- ${firstLetter(lastName)}${slicedWord(lastName, 15, 1)}`}
- primaryTypographyProps={{ color: '#ffffff', fontSize: 20, fontWeight: 500 }} />
- <ListItemText secondary={<span className={classes.statusCall}>
- ringing<span className={classes.animatedDots}>
- ...</span>
- </span>} secondaryTypographyProps={{ textAlign: "center" }} />
- </div>}
- <video className={share?classes.shareScreenActive:classes.shareScreenDisabled} ref={shareRef} playsInline muted autoPlay/>
- <div className={classes.bottomWrapper}>
- {!share&&<div className={classes.bottomItem}>
- <Avatar className={classes.bottomIcon} onClick={handleShareScreen}
- sx={{backgroundColor: '#ffffff',color: 'rgb(36, 36, 36)', width: 44, height: 44,zIndex:0}}>
- <ScreenShareIcon fontSize="medium" />
- </Avatar>
- <Typography variant="h6" className={classes.titleIconBottom}>Screencast</Typography>
- </div>}
- <div className={classes.bottomItem}>
- <Avatar className={classes.bottomIcon} onClick={handleVideo}
- sx={{backgroundColor: video?'rgb(88, 88, 88)':'#ffffff',color: video?'#ffffff':'rgb(36, 36, 36)', width: 44, height: 44,zIndex:0}}>
- {video?<VideocamOffIcon fontSize="medium" />:<VideocamIcon fontSize="medium" />}
- </Avatar>
- <Typography variant="h6" className={classes.titleIconBottom}>{video?'Stop Video':'Start Video'}</Typography>
- </div>
- <div className={classes.bottomItem}>
- <Avatar className={classes.bottomIcon}
- sx={{backgroundColor: '#f02a2a',color: '#ffffff', width: 44, height: 44,zIndex:0}}>
- <CallEndIcon fontSize="medium" />
- </Avatar>
- <Typography variant="h6" className={classes.titleIconBottom}>End Call</Typography>
- </div>
- <div className={classes.bottomItem}>
- <Avatar className={classes.bottomIcon} onClick={handleAudio}
- sx={{backgroundColor: audio?'rgb(88, 88, 88)':'#ffffff',color: audio?'#ffffff':'rgb(36, 36, 36)', width: 44, height: 44,zIndex:0}}>
- {audio?<MicIcon fontSize="medium" />:<MicOffIcon fontSize="medium" />}
- </Avatar>
- <Typography variant="h6" className={classes.titleIconBottom}>{audio?'Mute':'Unmute'}</Typography>
- </div>
- </div>
- </div>
- </div>
- )
- }
- export default CallModal
|