- {user.last_mess.unread ?
-
+
+
{user.username}
+
+ {user.last_mess.unread ?
+
- {user.last_mess.content}
+ :
+
+ {user.last_mess.content}
+ }
+
{user.last_mess.timestamp}
diff --git a/src/components/Conversation.js b/src/components/Conversation.js
index 81028f4..5f1c978 100644
--- a/src/components/Conversation.js
+++ b/src/components/Conversation.js
@@ -4,10 +4,10 @@ import { wsIP, serverIP } from '../config.js';
import { useLocation, useNavigate } from 'react-router-dom';
import ConfirmationDialog from './ConfirmationDialog.js';
import { useUser } from '../context/userContext.js';
-import Cookies from 'js-cookie';
import { useDispatch, useSelector } from 'react-redux';
-import { setMessages, addMessage, removeMessage } from '../features/messages/messagesSlice.js';
+import { addMessage, removeMessage } from '../features/messages/messagesSlice.js';
+import { lastMessage } from '../features/messages/usersSlice.js';
const Conversation = ( props ) => {
@@ -21,6 +21,7 @@ const Conversation = ( props ) => {
// User data from the useContext.js
const { user } = useUser();
+ console.log('user', user)
const dispatch = useDispatch();
const allMessages = useSelector((state) => state.messages);
@@ -46,12 +47,6 @@ const Conversation = ( props ) => {
const ws = new WebSocket(`${wsIP}/ws/conversation/${conv_name}/?userId=${user.id}&receiverId=${receiver.id}&token=${user.token}`);
const wsu = new WebSocket(`${wsIP}/ws/AllUsers/${conv_name}/?userId=${user.id}&token=${user.token}`);
- // const messages = null
-
- // if (conversation) {
- // messages = useSelector((state) => state.messages.filter((message) => message.conversation === conversation));
- // }
-
// Show the bottom message with open the chat;
// chatContainerRef is a var of useRef;
// current means the curren element(chat): '
';
@@ -59,101 +54,53 @@ const Conversation = ( props ) => {
const [hasScrolled, setHasScrolled] = useState(false);
+ // useEffect(() => {
+ // if ( !hasScrolled ) {
+ // window.scrollTo({ top: chatContainerRef.current.scrollHeight})
+ // }
+ // // console.log('window.scrollTo', chatContainerRef.current.scrollHeight)
+ // }, [])
+
useEffect(() => {
- if ( !hasScrolled ) {
- window.scrollTo({ top: chatContainerRef.current.scrollHeight})
- }
- // console.log('window.scrollTo', chatContainerRef.current.scrollHeight)
- }, [])
+ window.scrollTo({ top: chatContainerRef.current.scrollHeight})
+ })
useEffect(() => {
- // // Fetch conversation data for the selected user based on userId.
- // axios
- // .post(
- // `${serverIP}/conversations/`,
- // {
- // user: [parseInt(user.id), receiver.id],
- // },
- // {
- // headers: {
- // Authorization: `Bearer ${user.token}`,
- // },
- // }
- // )
- // .then((response) => {
- // const conversationData = response.data.conversation;
- // setConversation(conversationData.id);
-
- // // console.log('messages before axios', messages)
-
- // // Check if messages for this conversation already exist in the state
- // // setMessages_(allMessages.filter((message) => message.conversation === conversationData.id));
- // // console.log('messages setMymessages', messages.filter((message) => message.user_id === receiver.id))
-
- // console.log('conversation ID before', conversation, conversationData.id);
- // // dispatch(setConvId(conversationData.id));
- // // if (messages.length === 0 || Cookies.get('userId') !== conversationData.id) {
- // // console.log('conversation ID previouse', Cookies.get('userId'), conversationData.id);
- // // getConvMess(conversationData.id)
- // // }
- // console.log('conversationData', conversationData);
- // // checkConversation(conversationData.id)
-
- // })
- // .catch((error) => {
- // console.error('Error fetching conversation data:', error);
- // if(error.response.status === 403){
- // navigate('/login')
- // }else if (error.response.status === 404){
- // navigate('/404')
- // }
- // });
-
-
- // wsu.onmessage = (event) => {
- // const dataU = JSON.parse(event.data);
- // console.log('dataU', dataU);
- // if (dataU.type === 'mess_count'){
- // console.log('mess_count', dataU);
- // }
- // }
-
// message logic
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
console.log('message', message);
if (message.type === 'message_deleted') {
console.log('message_deleted', message.id);
- // Handle message deletion by filtering out the deleted message
- // setMessages((prevMessages) => {
- // const updatedMessages = prevMessages.filter((msg) => msg.id !== message.id);
- // console.log('updatedMessages', updatedMessages);
- // return updatedMessages;
- // });
dispatch(removeMessage(message.id));
- } else {
+ } else if ( message.type === 'resend_message' ) {
+ console.log('resend_message', message.id);
+ }
+ else {
console.log('received new message', message);
setHasScrolled(false) // Get you to the bottom of the page if is incoming data from the server
- // setMessages((prevMessages) => [
- // ...prevMessages,
- // {
- // id: message.id,
- // content: message.content,
- // username: message.username,
- // unread: message.unread,
- // photo: message.photo
- // }
- // ]);
+
dispatch(addMessage({
id: message.id,
content: message.content,
username: message.username,
+ user_id: message.user_id,
unread: message.unread,
photo: message.photo,
conversation_id: message.conversation_id,
}));
+
+ dispatch(lastMessage({
+ user_id: receiver.id,
+ last_mess: {
+ content: message.content,
+ timestamp: '10',
+ unread: message.unread,
+ },
+ }));
+
}
}
@@ -168,37 +115,8 @@ const Conversation = ( props ) => {
}, []);
-
- // const checkConversation = (id) => {
- // if (messages.length === 0 || conversation === id) {
- // console.log('conversation ID previouse', conversation, id);
- // getConvMess(id)
- // }
- // }
-
-
-// const getConvMess = ((id) => {
-// console.log('getConvMess', id)
-// axios.get(`${serverIP}/getConversation/${id}/`,{
-
-// headers: {
-// Authorization: `Bearer ${user.token}`,
-// userId: user.id,
-// },
-
-// })
-// .then((response) => {
-// console.log('getConvMess-response', response.data.messages)
-// // setMessages(response.data.messages)
-// // Use the setMessages action to store messages in the Redux store
-// // dispatch(setMessages(response.data.messages));
-// })
-// .catch((error) => {
-// console.error('Error fetching getConvMess data:', error);
-// })
-// })
-
const sendMessage = () => {
+
if (socket && socket.readyState === WebSocket.OPEN) {
if (newMessage) {
// dispatch(addMessage(newMessage));
@@ -212,14 +130,9 @@ const Conversation = ( props ) => {
}
}
- // if (socketU && socketU.readyState === WebSocket.OPEN) {
- // console.log('socketU', 'ok');
- // console.log('socketU data', socketU);
- // socketU.send(JSON.stringify({type: 'new_message_count', count: 1 }));
- // }
-
};
+
const handleChange = (e) => {
setNewMessage(e.target.value);
};
@@ -317,7 +230,7 @@ const delQuest = () => {
{ receiver.photo ?
:
-
+
}
{showConfirmation ?
@@ -355,13 +268,13 @@ const delQuest = () => {
{messages.map((message, index) => (
- {message.username === user.username ?
+ {message.user_id === user.id ?
{message.photo ?
:
-
+
}
confirmDelete(message.id)}>{message.content}{' '}
@@ -379,7 +292,7 @@ const delQuest = () => {
{message.photo ?
:
-
+
}
{message.content}
@@ -391,7 +304,7 @@ const delQuest = () => {
{message.photo ?
:
-
+
}
{message.content}
diff --git a/src/components/Header.js b/src/components/Header.js
index 35daa03..e57ec85 100644
--- a/src/components/Header.js
+++ b/src/components/Header.js
@@ -7,14 +7,23 @@ import {serverIP} from '../config.js';
import '../styles/Header.css';
import { useUser } from '../context/userContext.js';
+import { useDispatch, useSelector } from 'react-redux';
+import { setUser, clearUsers } from '../features/messages/usersSlice.js'
+import { setMessages, clearMessages } from '../features/messages/messagesSlice.js';
+
const Header = () => {
+ const dispatch = useDispatch();
+
const navigate = useNavigate();
const { user } = useUser();
// Handle user logout
const handleLogout = async () => {
+ dispatch(clearUsers())
+ dispatch(clearMessages())
+
try {
const userId = user.id;
// Send a POST request with user ID and token
diff --git a/src/components/auth/Logout.js b/src/components/auth/Logout.js
index 58b091c..2b64a3e 100644
--- a/src/components/auth/Logout.js
+++ b/src/components/auth/Logout.js
@@ -4,8 +4,14 @@ import axios from 'axios';
import {serverIP} from '../../config';
import {useUser} from '../../context/userContext.js'
+import { useDispatch, useSelector } from 'react-redux';
+import { setUser } from '../../features/messages/usersSlice.js'
+import { setMessages } from '../../features/messages/messagesSlice.js';
+
const Logout = () => {
+ const dispatch = useDispatch();
+
const { user } = useUser();
const navigate = useNavigate();
const userId = user.id;
@@ -14,6 +20,9 @@ const Logout = () => {
// Handle user logout
const handleLogout = async () => {
+ dispatch(setUser(null))
+ dispatch(setMessages(null))
+
try {
console.log('token', user.token)
diff --git a/src/features/messages/messagesSlice.js b/src/features/messages/messagesSlice.js
index fd00c12..8cc610b 100644
--- a/src/features/messages/messagesSlice.js
+++ b/src/features/messages/messagesSlice.js
@@ -1,7 +1,4 @@
-import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
-import axios from 'axios';
-import { serverIP } from '../../config';
-import { useUser } from '../../context/userContext';
+import { createSlice } from '@reduxjs/toolkit';
// Users slice
const messagesSlice = createSlice({
@@ -17,60 +14,11 @@ const messagesSlice = createSlice({
removeMessage: (state, action) => {
return state.filter((message) => message.id !== action.payload);
},
+ clearMessages: (state) => {
+ return [];
+ },
},
});
- export const { setConvId, setMessages, addMessage, removeMessage } = messagesSlice.actions;
- export default messagesSlice.reducer;
-
-
-// import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
-// import axios from 'axios';
-// import { serverIP } from '../../config';
-// import { useUser } from '../../context/userContext';
-
-// // Async thunk for fetching messages for a specific conversation
-// export const fetchMessages = createAsyncThunk('messages/fetchMessages', async (conversationId) => {
-// const { user } = useUser();
-// // const existingMessages = getState().messages[conversationId]; // Check if messages for this conversation already exist in the state
-
-// // If messages are already in the state, return them
-// // if (existingMessages) {
-// // return existingMessages;
-// // }
-
-// const response = await axios.get(`${serverIP}/getConversation/${conversationId}/`, {
-// headers: {
-// Authorization: `Bearer ${user.token}`,
-// userId: user.id,
-// },
-// });
-
-// return response.data.messages;
-// });
-
-// // Messages slice
-// const messagesSlice = createSlice({
-// name: 'messages',
-// initialState: {},
-// reducers: {
-// setMessages: (state, action) => {
-// const { conversationId, messages } = action.payload;
-// state[conversationId] = messages;
-// },
-// addMessage: (state, action) => {
-// const { conversationId, message } = action.payload;
-// state[conversationId].push(message);
-// },
-// removeMessage: (state, action) => {
-// const { conversationId, messageId } = action.payload;
-// state[conversationId] = state[conversationId].filter((message) => message.id !== messageId);
-// },
-// },
-// });
-
-// // Export action creators
-// export const { setMessages, addMessage, removeMessage } = messagesSlice.actions;
-
-// // Export the reducer
-// export default messagesSlice.reducer;
+ export const { setConvId, setMessages, addMessage, removeMessage, clearMessages } = messagesSlice.actions;
+ export default messagesSlice.reducer;
\ No newline at end of file
diff --git a/src/features/messages/usersSlice.js b/src/features/messages/usersSlice.js
new file mode 100644
index 0000000..49c6b6e
--- /dev/null
+++ b/src/features/messages/usersSlice.js
@@ -0,0 +1,38 @@
+import { createSlice } from '@reduxjs/toolkit';
+
+// Users slice
+const usersSlice = createSlice({
+ name: 'users',
+ initialState: [],
+ reducers: {
+ setUser: (state, action) => {
+ return action.payload;
+ },
+ addUser: (state, action) => {
+ state.push(action.payload);
+ },
+ lastMessage: (state, action) => {
+ console.log('lastMessage reducer called with action:', action);
+ // Find the user by user_id
+ const userToUpdate = state.find((user) => user.id === action.payload.user_id);
+
+ // If the user is found, update their lastMessage
+ if (userToUpdate) {
+ userToUpdate.last_mess = {
+ content: action.payload.last_mess.content,
+ timestamp: action.payload.last_mess.timestamp,
+ unread: action.payload.last_mess.unread,
+ };
+ }
+ },
+ removeUser: (state, action) => {
+ return state.filter((user) => user.id !== action.payload);
+ },
+ clearUsers: (state) => {
+ return [];
+ },
+ },
+ });
+
+ export const { setUser, addUser, lastMessage, removeUser, clearUsers } = usersSlice.actions;
+ export default usersSlice.reducer;
\ No newline at end of file
diff --git a/src/media/profile.png b/src/media/profile.png
new file mode 100644
index 0000000..e1a28b3
Binary files /dev/null and b/src/media/profile.png differ
diff --git a/src/store.js b/src/store.js
index 531d182..6eae197 100644
--- a/src/store.js
+++ b/src/store.js
@@ -1,9 +1,11 @@
import { configureStore } from '@reduxjs/toolkit';
import messagesReducer from '../src/features/messages/messagesSlice.js';
+import usersReducer from '../src/features/messages/usersSlice.js';
const store = configureStore({
reducer: {
messages: messagesReducer,
+ users: usersReducer,
},
});