瀏覽代碼

work on call

unknown 2 年之前
父節點
當前提交
7a14fb4f7e
共有 3 個文件被更改,包括 49 次插入30 次删除
  1. 1 1
      .eslintcache
  2. 45 28
      src/components/HomePage/CallBar/index.tsx
  3. 3 1
      src/helpers/index.ts

File diff suppressed because it is too large
+ 1 - 1
.eslintcache


+ 45 - 28
src/components/HomePage/CallBar/index.tsx

@@ -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}>

+ 3 - 1
src/helpers/index.ts

@@ -53,7 +53,8 @@ const getTimeBySeconds = (seconds: number) =>
 
 const playNotification = (url:string) => {
   const audio = new Audio(url);
-  audio.play();
+  audio.play()
+  return audio;
 }
 
 const notification = (name: string, onClick: () => void) => {
@@ -110,6 +111,7 @@ const playNotificationWithoutPermission = (url: string) => {
         request.send();
     })
     .catch(reason => console.error(`Audio permissions denied: ${reason}`));
+  return audioContext
 }
 
 const handleDownload = async (url: string, type: string) => await FileSaver.saveAs(url, type);