Skip to content

Commit

Permalink
Merge pull request #19 from Messaging-Application/improvements
Browse files Browse the repository at this point in the history
fix pagination issue
  • Loading branch information
nefelitav authored Mar 18, 2024
2 parents 9faa64e + d82495c commit ac024e3
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 10 deletions.
4 changes: 1 addition & 3 deletions src/components/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,7 @@ const Chat: React.FC<ChatProps> = ({ socket }) => {
// Effect to listen for incoming messages from the socket
useEffect(() => {
setMessages([]);
console.log("selected user");
socket.onmessage = (event) => {
console.log("listening");
const newMessage = JSON.parse(event.data);
// const userString = localStorage.getItem("user");
// if (userString) {
Expand All @@ -53,7 +51,7 @@ const Chat: React.FC<ChatProps> = ({ socket }) => {

return (
<div className="chat">
<UsersList setShowProfile={setShowProfile} setSelectedUser={setSelectedUser} handleShowUser={handleShowUser} setChatId={setChatId}/>
<UsersList setShowProfile={setShowProfile} setSelectedUser={setSelectedUser} handleShowUser={handleShowUser} setChatId={setChatId} socket={socket}/>
<div className="chatMain">
<ChatHeader socket={socket} setShowProfile={setShowProfile} selectedUser={selectedUser} handleShowUser={handleShowUser} setSelectedUser={setSelectedUser}/>
{!showProfile && (
Expand Down
99 changes: 92 additions & 7 deletions src/components/UsersList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,71 @@ import React, { useState, useEffect } from 'react';
import { UsersListProps, UserData, UserWithChatData } from "../types";
import "../index.css";

const UsersList: React.FC<UsersListProps> = ({ setShowProfile, setSelectedUser, handleShowUser, setChatId }) => {
const UsersList: React.FC<UsersListProps> = ({ setShowProfile, setSelectedUser, handleShowUser, setChatId, socket }) => {
// State variables
const [users, setUsers] = useState<UserWithChatData[]>([]);
const [currentPage, setCurrentPage] = useState(0);
const [totalPages] = useState(3);
const [numberOfUsers, setNumberOfUsers] = useState<number>(0);
const [addedUsers, setAddedUsers] = useState<number>(0);
const [newUsers, setNewUsers] = useState<number>(0);
const [totalPages, setTotalPages] = useState<number>(0);
const [nextPage, setNextPage] = useState<boolean>(false);
const pageSize : number = 3;
console.log(socket);
const [isLoading, setIsLoading] = useState(false); // State to track loading state
// Get user from local storage
const userString = localStorage.getItem("user");
const user: UserData | null = userString ? JSON.parse(userString) : null;
// const [onlineUsers, setOnlineUsers] = useState([]);

// useEffect(() => {
// console.log("!!!");
// // Function to fetch online users
// const fetchOnlineUsers = async () => {
// console.log("!!");
// try {
// // Send a message to the WebSocket server indicating you want to fetch online users
// if (socket.readyState === WebSocket.OPEN) {
// // Send a message to the WebSocket server indicating you want to fetch online users
// const msg = {
// "action" : "getOnlineUsers",
// "sender_id": String(user?.id)
// };
// socket.send(JSON.stringify(msg));
// } else {
// console.log("WebSocket connection is still in CONNECTING state.");
// }
// } catch (err) {
// console.log(err);
// }
// };
// console.log("!!!!!");
// fetchOnlineUsers();
// // Set up an interval to fetch online users every 5 minutes (300000 milliseconds)
// const interval = setInterval(() => {
// fetchOnlineUsers();
// }, 9999999999999999999999999999999999999999999999999999);

// // Handle messages received from WebSocket server
// socket.onmessage = (event) => {
// console.log("-----", event.data);
// const data = JSON.parse(event.data);
// if (data.action === 'updateOnlineUsers') {
// // Update online users state with data received from WebSocket server
// setOnlineUsers(data.online_user_ids);
// }
// };
// console.log(onlineUsers);

// // Clean up function to clear interval on component unmount
// return () => clearInterval(interval);
// }, []); // Empty dependency array ensures useEffect runs only once after initial render

useEffect(() => {
const fetchUsers = async () => {
try {
setIsLoading(true); // Set loading state to true
const response = await fetch(`http://localhost:8081/user/all?pageNo=${currentPage}&pageSize=${totalPages}`, {
const response = await fetch(`http://localhost:8081/user/all?pageNo=${currentPage}&pageSize=${pageSize}`, {
method: "GET",
credentials: "include",
headers: {
Expand All @@ -34,36 +84,51 @@ const UsersList: React.FC<UsersListProps> = ({ setShowProfile, setSelectedUser,
// Parse the response body as JSON
const responseBody = await response.json();

setTotalPages(responseBody.totalPages);
const redisData = responseBody.redisData;

// Update users state with new data
// Do not add duplicates
for (const key in responseBody) {
setAddedUsers(0);
let counter = 0;
for (const key in redisData) {
const tokens = key.split("chat:");
const parsedResponse = JSON.parse(responseBody[key]);
const parsedResponse = JSON.parse(redisData[key]);
setUsers(users => {
const userSet = new Set(users.map(user => user.user.id));
if (String(user?.id) === parsedResponse.user2.id) {
if (!userSet.has(parsedResponse.user1.id)) {
counter++;
return [...users, { user: parsedResponse.user1, chat_id: tokens[1] }];
}
} else if (String(user?.id) === parsedResponse.user1.id) {
if (!userSet.has(parsedResponse.user2.id)) {
counter++;
return [...users, { user: parsedResponse.user2, chat_id: tokens[1] }];
}
}
// Return the current state when conditions don't match
return users;
});
}
setNumberOfUsers(prevNumberOfUsers => prevNumberOfUsers + counter);
setAddedUsers(prevAddedUsers => prevAddedUsers + counter);

setIsLoading(false); // Set loading state to false
// if (addedUsers === 0) {
// if ((numberOfUsers % pageSize === 0) && currentPage > 0) {
// console.log("decrementing - current page: ", currentPage, " number of users: ", numberOfUsers);
// setCurrentPage(currentPage - 1);
// }
// }

} catch (error) {
console.error('Error fetching users:', error);
setIsLoading(false); // Set loading state to false even in case of error
}
};
fetchUsers();
}, [currentPage, totalPages, user?.id]); // the dependencies
}, [currentPage, user?.id, newUsers]); // the dependencies


return (
Expand Down Expand Up @@ -96,7 +161,27 @@ const UsersList: React.FC<UsersListProps> = ({ setShowProfile, setSelectedUser,
</div>
{!isLoading && (
<div style={{ display: "flex", justifyContent: "center", marginTop: "10px" }}>
<button style={{float:"right", marginRight:"10px"}} className="leaveChatButton" onClick={() => setCurrentPage(currentPage + 1)} aria-label="Load more">
<button style={{float:"right", marginRight:"10px"}} className="leaveChatButton"
onClick={() => {
// console.log("current page = ", currentPage, "number of users = ", numberOfUsers, "added users = ", addedUsers);

if (addedUsers !== 0 && nextPage === true) {
setNextPage(false);
}
// case that there are less elements in page than expected
if (totalPages > currentPage + 1 && addedUsers === 0) {
setCurrentPage(currentPage + 1);
} else if (addedUsers === 0 && nextPage === true) {
console.log("got nothing, stay in ", currentPage);
} else if ((numberOfUsers % pageSize === 0) && numberOfUsers != 0) {
setCurrentPage(currentPage + 1);
setNextPage(true);
} else {
console.log("not full page - number of users: ", numberOfUsers);
}
setNewUsers(newUsers + 1);
}}
aria-label="Load more">
Load more
</button>
</div>
Expand Down
1 change: 1 addition & 0 deletions src/types/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export interface UsersListProps {
setSelectedUser: React.Dispatch<React.SetStateAction<UserData | null>>;
handleShowUser: (user: UserData | null) => void;
setChatId: React.Dispatch<React.SetStateAction<string>>;
socket: WebSocket;
}

export interface UserData {
Expand Down

0 comments on commit ac024e3

Please sign in to comment.