Преглед изворни кода

add dataReducer and private chat header v1 and fix some bugs with socket

serg1557733 пре 1 година
родитељ
комит
3134362900

+ 15 - 20
frontend/src/components/chatPage/generalChat/FindUserBox.jsx

@@ -1,8 +1,9 @@
 import { useSelector } from 'react-redux';
 import { useState } from 'react';
 import './userInfo.scss';
-import { store } from '../../../store';
 import {UserInfoButton} from './UserInfoButton';
+
+
 export const FindUserBox = () => {
 
     const allUsers = useSelector(state => state.getUserSocketReducer.allUsers)
@@ -13,24 +14,18 @@ export const FindUserBox = () => {
  
     return (
         <>
-        <div 
-            className={'online'}                       
-        >  
-            <div>Find users to write</div>
-            <input style={{width:'80%'}}
-                    value = {findUser} 
-                    onChange={(e) => {
-                        setfindUser(e.target.value)
-                        setShowUsers(true)
-                        }} >
-                
-            </input>
-
-           
-
-        </div>
-        { showUsers && findUser.length > 0  && res.map((item, i) => <UserInfoButton item = {item} i = {i}  key={i}/>  )}
-
-    </>
+            <div className='online'>  
+                <div>Find users to write</div>
+                <input style={{width:'80%'}}
+                        value = {findUser} 
+                        onChange={(e) => {
+                            setfindUser(e.target.value)
+                            setShowUsers(true)
+                            }} >
+                    
+                </input>
+            </div>
+            {showUsers && findUser.length > 0  && res.map((item, i) => <UserInfoButton item = {item} i = {i}  key={i}/> )}
+        </>
     )
 }

+ 3 - 6
frontend/src/components/chatPage/generalChat/UserInfoButton.jsx

@@ -4,6 +4,8 @@ import { useSelector } from "react-redux";
 import { StyledAvatar } from "../messageForm/StyledAvatar";
 import { Avatar } from "@mui/material";
 import { useState } from "react";
+import { useDispatch } from 'react-redux';
+import {selectedUser} from "../../../reducers/dataReducers";
 
 export const UserInfoButton = ({item, i}) => {
 
@@ -24,12 +26,7 @@ export const UserInfoButton = ({item, i}) => {
         <div 
         className={(item.socketId&&isPrivatChat&&(chatId === item.socketId))? 'online active' :'online' }                       
         onClick={(e) => {
-            console.log(e.target.lastChild.textContent)
-            // if (item.userName == e.target.lastChild.textContent){
-            //     e.target.lastChild.textContent.add('arrow')}
-            //     else {
-            //         e.target.classList.remove('arrow')
-            //     };
+            store.dispatch(selectedUser(item.userName))
             store.dispatch(privateMessage({toUser: item}))
             socket.emit('privat chat', {
                 user,

+ 12 - 0
frontend/src/components/chatPage/messageForm/userInfo.scss

@@ -0,0 +1,12 @@
+.userAvatar {
+    background-color: grey;
+    width: 100px;
+    height: 100px;
+    font-size: 14;
+    margin: 20px auto;
+}
+
+.active {
+    background-color:rgb(30, 8, 62);
+}
+

+ 7 - 4
frontend/src/components/chatPage/privateChat/PrivatChatHeader.jsx

@@ -1,10 +1,13 @@
+import { useSelector } from "react-redux"
+import './userInfo.scss';
 export const PrivatChatHeader = ({userName}) => {
 
 //add dispatch and saving name for user to store
+const selectedUser = useSelector(state => state.dataReducer.selectedUser)
 
     return (
-        <>
-            <span> You and {userName} </span>
-        </>
+        <div className="active" >
+            <div > Private Chat with {selectedUser.toUpperCase()} </div>
+        </div>
     )
-}
+}

+ 92 - 89
frontend/src/components/chatPage/privateChat/PrivateChat.jsx

@@ -8,9 +8,10 @@ import { editMessage } from '../../../reducers/messageReducer';
 import { MessageEditorMenu } from '../MessageEditorMenu.jsx';
 import imgBtn from '../../../assets/img/gg.png';
 import useSound from 'use-sound';
-import notifSound from '../../../assets/get.mp3'
 import { PrivatChatHeader } from './PrivatChatHeader';
+import notifSound from '../../../assets/get.mp3'
 
+//need to fix update wenn message sendet and icon for new private messages
 
 export const PrivateChat = () => {
 
@@ -21,6 +22,7 @@ export const PrivateChat = () => {
 
     const user = useSelector(state => state.getUserSocketReducer.socketUserData)
     const storeMessageId = useSelector(state => state.messageReducer.messageId)
+    const selectedUser = useSelector(state => state.dataReducer.selectedUser)
 
     const [startMessages, setStartMessages] = useState([])   
     let endMessages = useRef(null);
@@ -48,101 +50,102 @@ socket.on("private message", (message)=> {
         }
       }, [startMessages]);
            
-
     return (  
-        
-            <Box className='messageBox'>  
+
+        <>
+            <PrivatChatHeader/>
+                <Box className='messageBox'>  
                 
-                {
-                startMessages.map((item, i) =>
-                    <div key={i + 1} className={ 
-                        (item.fromUser === user._id)? 'message myMessage' :'message'}
-                        onClick = {(e) => {
-                            console.log(e.target)
-                            if(e.target.closest("div").className.includes('myMessage') && (item.userName === user.userName) && (item.text === e.target.textContent)){
-                                e.currentTarget.className += ' editMessage'  
-                                dispatch(editMessage({socket, editMessage: e.target.textContent, messageId: item._id}))  
-                                setIsEditing(true)
-                                }
-                        }}
-                        > 
-                        {storeMessageId === item._id ? <MessageEditorMenu />: ""} 
-                        <span
-                            style={{'alignItems': 'center',
-                                    marginLeft: 5, 
-                                    fontStyle: 'italic', 
-                                    fontWeight: 800
-                                }}
-
-                        > {item.fromUser}</span>
-                        <div 
-                            key={i}
-                        
-                            className={ 
-                                (item.fromUser === user._id)? 'message myMessage' :'message'}>
-                           
-                           { 
-                           item.text.match(regYoutube) ?
-                           <iframe 
-                                width="280" 
-                                height="160" 
-                                style={{'maxWidth': "90%"}}
-                                src={`https://www.youtube.com/embed/`+ (item.text.match(regYoutube)[1])}
-                                title="YouTube video player" 
-                                allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" 
-                                allowFullScreen> 
-                                
-                            </iframe>
-                            :
-                            (item.file && item.fileType && item.fileType.split('/')[0] !== 'image') ? 
-
-                            <div style={{'display': 'flex', 'alignItems': 'center'}} >
-
-                                <a href={SERVER_URL + '/' +item.file} download> 
-                                    <Button
-                                        variant="contained" 
-                                        component="label"
-                                        sx = {{
-                                            minWidth: 'auto',
-                                            minHeight: '25px',
-                                            backgroundImage:'url(' + imgBtn + ')' ,
-                                            backgroundPosition: 'center', 
-                                            backgroundRepeat: "no-repeat", 
-                                            backgroundSize: '15px 20px',
-                                            backgroundColor: '#d3d3d3'
-
-                                        }}  
-                                    >
-                                    </Button>  
-                                </a>
-                                <p style={{'marginLeft': '15px'}}  >{item.text}</p>  
-                            </div>
-                        : 
-                            <p>{item.text}</p>
-                          
-                           }
-
-                        { 
-                            (item.file && item.fileType && item.fileType.split('/')[0] == 'image' ) //need to fix for other type files
-                            ? 
-                                <img width={'auto'} style={{'maxWidth': "90%"}} src={ SERVER_URL + '/' + item.file} alt={'error load image'}/>
-                            :
-                            ''
-                        }
+                    {
+                    startMessages.map((item, i) =>
+                        <div key={i + 1} className={ 
+                            (item.fromUser === user._id)? 'message myMessage' :'message'}
+                            onClick = {(e) => {
+                                console.log(e.target)
+                                if(e.target.closest("div").className.includes('myMessage') && (item.userName === user.userName) && (item.text === e.target.textContent)){
+                                    e.currentTarget.className += ' editMessage'  
+                                    dispatch(editMessage({socket, editMessage: e.target.textContent, messageId: item._id}))  
+                                    setIsEditing(true)
+                                    }
+                            }}
+                            > 
+                            {storeMessageId === item._id ? <MessageEditorMenu />: ""} 
+                            <span
+                                style={{'alignItems': 'center',
+                                        marginLeft: 5, 
+                                        fontStyle: 'italic', 
+                                        fontWeight: 800
+                                    }}
+
+                            > {item.fromUser}</span>
+                            <div 
+                                key={i}
+                            
+                                className={ 
+                                    (item.fromUser === user._id)? 'message myMessage' :'message'}>
+                            
+                            { 
+                            item.text.match(regYoutube) ?
+                            <iframe 
+                                    width="280" 
+                                    height="160" 
+                                    style={{'maxWidth': "90%"}}
+                                    src={`https://www.youtube.com/embed/`+ (item.text.match(regYoutube)[1])}
+                                    title="YouTube video player" 
+                                    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" 
+                                    allowFullScreen> 
+                                    
+                                </iframe>
+                                :
+                                (item.file && item.fileType && item.fileType.split('/')[0] !== 'image') ? 
+
+                                <div style={{'display': 'flex', 'alignItems': 'center'}} >
+
+                                    <a href={SERVER_URL + '/' +item.file} download> 
+                                        <Button
+                                            variant="contained" 
+                                            component="label"
+                                            sx = {{
+                                                minWidth: 'auto',
+                                                minHeight: '25px',
+                                                backgroundImage:'url(' + imgBtn + ')' ,
+                                                backgroundPosition: 'center', 
+                                                backgroundRepeat: "no-repeat", 
+                                                backgroundSize: '15px 20px',
+                                                backgroundColor: '#d3d3d3'
+
+                                            }}  
+                                        >
+                                        </Button>  
+                                    </a>
+                                    <p style={{'marginLeft': '15px'}}  >{item.text}</p>  
+                                </div>
+                            : 
+                                <p>{item.text}</p>
+                            
+                            }
+
+                            { 
+                                (item.file && item.fileType && item.fileType.split('/')[0] == 'image' ) //need to fix for other type files
+                                ? 
+                                    <img width={'auto'} style={{'maxWidth': "90%"}} src={ SERVER_URL + '/' + item.file} alt={'error load image'}/>
+                                :
+                                ''
+                            }
 
+                            </div>
+                            {isEditiedMessage && <i>Edited</i>}
+                            <div className={ 
+                                    (item.fromUser === user._id)? 'myDate' :'date'}>
+                                    {dateFormat(item).time}
+                            </div>
                         </div>
-                        {isEditiedMessage && <i>Edited</i>}
-                        <div className={ 
-                                 (item.fromUser === user._id)? 'myDate' :'date'}>
-                                {dateFormat(item).time}
-                        </div>
-                    </div>
-                )}
+                    )}
 
-                <div ref={endMessages}></div>
+                    <div ref={endMessages}></div>
 
             </Box>
-        
+        </>      
     )
 
     

+ 17 - 0
frontend/src/components/chatPage/privateChat/userInfo.scss

@@ -0,0 +1,17 @@
+.userAvatar {
+    background-color: grey;
+    width: 100px;
+    height: 100px;
+    font-size: 14;
+    margin: 20px auto;
+}
+
+.active {
+    background-color:rgb(30, 8, 62);
+    border-radius: 5px;
+    padding: 5px;
+    font-weight: 700;
+    text-align: center;
+    color:azure;
+}
+

+ 26 - 0
frontend/src/reducers/dataReducers.js

@@ -0,0 +1,26 @@
+import {createSlice } from '@reduxjs/toolkit';
+
+const initialState = {
+    selectedUser: ''
+}
+
+export const dataReducersSlice = createSlice({
+    name: 'dataReducer',
+    initialState,
+    reducers: {
+        selectedUser: (state, action) => {
+                state.selectedUser = action.payload  
+      }
+    },
+  })
+  
+  // Action creators are generated for each case reducer function
+
+const {actions, reducer} = dataReducersSlice;
+const dataReducer = reducer;
+
+export default dataReducer;
+
+export const {
+        selectedUser
+        } = actions;

+ 2 - 1
frontend/src/store.js

@@ -2,12 +2,13 @@
 import userDataReducer from './reducers/userDataReducer';
 import getUserSocketReducer from './reducers/socketReducer';
 import messageReducer from './reducers/messageReducer';
+import dataReducer from './reducers/dataReducers';
 import { configureStore } from '@reduxjs/toolkit';
 
 
 
 export  const store = configureStore({
-    reducer: {userDataReducer, getUserSocketReducer, messageReducer},
+    reducer: {userDataReducer, getUserSocketReducer, messageReducer, dataReducer},
     middleware: getDefaultMiddleware => getDefaultMiddleware({
         serializableCheck: false
       }),