Browse Source

add userTyping socket event and visual element to front

serg1557733 1 year ago
parent
commit
49007ab1d5

+ 12 - 7
backend/app.js

@@ -26,7 +26,6 @@ const io = require("socket.io")(server, {
         origin: "http://localhost:3000" //client endpoint and port
     }
 });
-const randomColor = require('randomcolor'); 
 
 const PORT = process.env.PORT || 5000;
 const TOKEN_KEY = process.env.TOKEN_KEY || 'rGH4r@3DKOg06hgj'; 
@@ -144,6 +143,7 @@ io.use( async (socket, next) => {
         usersOnline.push(sock.user);
     }) 
 
+
    
     try {
         const user = jwt.verify(token, TOKEN_KEY);
@@ -155,7 +155,6 @@ io.use( async (socket, next) => {
             return;
         }
         socket.user = user;
-        socket.user.color = randomColor();
         const exist = sockets.find((current) => current.user.userName == socket.user.userName)
 
         if(exist) {  //&& !user.isAdmin  - add for two or more admins 
@@ -173,10 +172,12 @@ io.on("connection", async (socket) => {
     const userName = socket.user.userName;
     const sockets = await io.fetchSockets();
     const dbUser = await getOneUser(userName);
-    
-    io.emit('usersOnline', sockets.map((sock) => sock.user)); // send array online users  
+
+
+    io.emit('usersOnline', sockets.map(sock => sock.user)); // send array online users  
+
     socket.emit('connected', dbUser); //socket.user
-   
+  
     if(socket.user.isAdmin){
          getAllDbUsers(socket); 
     }//sent all users from db to admin
@@ -224,11 +225,10 @@ io.on("connection", async (socket) => {
     try {
         socket.on("disconnect", async () => {
             const sockets = await io.fetchSockets();
-            io.emit('usersOnline', sockets.map((sock) => sock.user));
+            io.emit('usersOnline', sockets.map(sock => sock.user));
             console.log(`user :${socket.user.userName} , disconnected to socket`); 
         });
             console.log(`user :${socket.user.userName} , connected to socket`); 
-        
         socket.on("muteUser",async (data) => {
             if(!socket.user.isAdmin){
                 return;
@@ -265,6 +265,11 @@ io.on("connection", async (socket) => {
                 }
             // }
            });
+
+           socket.on('userWriting', async () => {
+                let isTyping = true;
+                io.emit('writing', {userName, isTyping})
+           })
     } catch (e) {
         console.log(e);
     }

+ 20 - 5
frontend/src/components/chatPage/ChatPage.jsx

@@ -26,28 +26,42 @@ export const ChatPage = () => {
     let showUserInfoBox = useSelector(state => state.messageReducer.showUserInfoBox)// || localStorage.getItem('showBox');
 
     const [message, setMessage] = useState({message: ''});
+    const [isUserTyping, setUserTyping] = useState([]);
     
     const isTabletorMobile = (window.screen.width < 730);
 
     useEffect(() => {
+        if(socket) {
+            socket.on('writing', (data) => { 
+                    setUserTyping(data) 
+                    setTimeout(() => setUserTyping([]), 500 )
+                })  
+        }
+   }, [socket])
+
+
+    useEffect(() => {
+   
         if(token){
-            SOCKET_EVENTS.map(event => dispatch(getSocket(event)))       
+            SOCKET_EVENTS.map(event => dispatch(getSocket(event)))   
         }
-    }, [token, editOldMessage, showUserInfoBox, ])
+    }, [token, editOldMessage, showUserInfoBox])
  
     return (
         <div className='rootContainer'>
 
             <Box className = 'rootBox'>
 
-
                 { isTabletorMobile ? <SwitchButton/> : null}
                 
                 <Box className ={isTabletorMobile ? 'rootMessageFormMobile':'rootMessageForm'} >
                     
                     <MessageForm/>
 
+                    {isUserTyping.isTyping && (isUserTyping.userName !== user.userName)? <span> User {isUserTyping.userName} typing..</span> : ""}
+
                     <Box 
+
                         component="form" 
                         onSubmit = {e  => {
                                         e.preventDefault()
@@ -64,7 +78,7 @@ export const ChatPage = () => {
                             margin: '20px 5px'}
                            
                         }>
-            
+
                         <TextareaAutosize
                             id="outlined-basic" 
                             label="Type a message..." 
@@ -85,6 +99,7 @@ export const ChatPage = () => {
                             }}
                             onChange={e => { 
                                 dispatch(storeMessage({message: e.target.value}))
+                                socket.emit('userWriting');
                                 setMessage({message: e.target.value})}
                             } 
                         
@@ -115,8 +130,8 @@ export const ChatPage = () => {
                         variant="outlined"
                         onClick={()=> {
                                 localStorage.removeItem('token');
-                                socket.disconnect(); 
                                 dispatch(removeToken());
+                                socket.disconnect(); 
                                 }}>
                         Logout
                     </Button>

+ 3 - 5
frontend/src/components/chatPage/messageForm/MessegaForm.jsx

@@ -1,19 +1,16 @@
 import { Avatar, Box, StyledBadge } from '@mui/material';
 import { dateFormat } from '../utils/dateFormat';
 import { useSelector } from 'react-redux';   
-import { Fragment, useRef, useEffect, useMemo} from 'react';
+import { useRef, useEffect} from 'react';
 import { scrollToBottom } from '../utils/scrollToBottom';
 import { useDispatch } from 'react-redux';
 import { editMessage } from '../../../reducers/messageReducer';
-import { TimeAgoMessage } from '../TimeAgoMessage';
 import { StyledAvatar } from './StyledAvatar';
 
-
-
-
 export const MessageForm = () => {
 
     const dispatch = useDispatch();
+
     const SERVER_URL = process.env.REACT_APP_SERVER_URL|| 'http://localhost:5000/';
 
     const startMessages = useSelector(state => state.getUserSocketReducer.startMessages)
@@ -23,6 +20,7 @@ export const MessageForm = () => {
 
     const endMessages = useRef(null);
 
+    const regYoutube = /http(?:s?):\/\/(?:www\.)?youtu(?:be\.com\/watch\?v=|\.be\/)([\w\-\_]*)(&(amp;)?‌​[\w\?‌​=]*)?/; //for youtube video
 
     useEffect(() => {
         scrollToBottom(endMessages)

+ 0 - 6
frontend/src/components/chatPage/userInfo/UserInfo.jsx

@@ -45,7 +45,6 @@ export const UserInfo = () => {
 
     let userAvatarUrl = SERVER_URL + (storeUserAvatar || user.avatar);
 
-
     const userNamesOnlineSet =  new Set(usersOnline.map( i => i.userName))
     
     
@@ -54,11 +53,6 @@ export const UserInfo = () => {
         dispatch(getUserAvatar(file))
         setDisplayType('none')
     }
-    //add delete avatar function later 
-
-
-  
-
 
     return (
             <>  

+ 3 - 0
frontend/src/reducers/messageReducer.js

@@ -20,6 +20,9 @@ export const editMessageToSocket = (state, data) => {
        } 
 };
 
+
+
+
 const messageReducerSlice = createSlice({
     name: 'messageReducer',
     initialState,

+ 23 - 5
frontend/src/reducers/socketReducer.js

@@ -10,7 +10,9 @@ const initialState = {
     socketUserData: {},
     usersOnline: [],
     startMessages: [],
-    allUsers: []
+    allUsers: [],
+    writing: false,
+    usersWriting: []
 }
 
 const SOCKET_URL =  process.env.REACT_APP_SERVER_URL || 'http://localhost:5000'; 
@@ -19,11 +21,12 @@ const connectToSocket = (event) => {
         try {
             const token = localStorage.getItem('token');
             if(token){
-                const socket = io.connect( 
+                const socket = io.connect(    //need to add other function for connecting
                     SOCKET_URL, 
                     {auth: {token}})
                     socket.on('connected', data => {
                                 store.dispatch(getUser(data));
+                               // socketEventsDispatch(socket)
                             })
                             .on(event, (data) => {
                                    switch (event){
@@ -54,6 +57,7 @@ const connectToSocket = (event) => {
                                 }
                             })
                             .on('error', e => {console.log('On connected', e)}); 
+                            
                 return socket;       
             }   
         } catch (error) {
@@ -61,7 +65,15 @@ const connectToSocket = (event) => {
         } 
     };
 
-    
+// const socketEventsDispatch = (socket) => {
+//     socket
+//         .on('writing', (data) => {
+//                 console.log(data)
+//                 store.dispatch(writing(data));   
+//      })
+// }
+
+
 export const getUserSocketSlice = createSlice({
     name: 'userSocket',
     initialState,
@@ -77,7 +89,12 @@ export const getUserSocketSlice = createSlice({
         getAllMessages: (state, action) => {state.startMessages = action.payload},
         getUsersOnline: (state, action) => {state.usersOnline = action.payload},
         getAllUsers: (state, action) => {state.allUsers = action.payload},
-        addNewMessage: (state, action) => {state.startMessages.push(action.payload)}
+        addNewMessage: (state, action) => {state.startMessages.push(action.payload)}, 
+        // writing: (state, action) => {
+        //                             state.writing = true;
+        //                             state.usersWriting.push(action.payload)                  
+        //     }
+        
         }
     }
 );
@@ -94,5 +111,6 @@ export const {
     getAllMessages,
     getUsersOnline,
     addNewMessage,
-    getAllUsers
+    getAllUsers,
+    writing
 } = actions;