diff --git a/.DS_Store b/.DS_Store
index 11c1dac..b370c47 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/backend/.DS_Store b/backend/.DS_Store
index 7967f16..04ef7ff 100644
Binary files a/backend/.DS_Store and b/backend/.DS_Store differ
diff --git a/backend/code/src/friends/friends.service.ts b/backend/code/src/friends/friends.service.ts
index c591434..cf417f1 100644
--- a/backend/code/src/friends/friends.service.ts
+++ b/backend/code/src/friends/friends.service.ts
@@ -223,29 +223,29 @@ export class FriendsService {
},
});
- return friends.map((friend: any) => {
+ return friends.map((friend) => {
if (friend.from.userId === userId) {
- friend = friend.to as any;
const avatar: PICTURE = {
- thumbnail: `https://res.cloudinary.com/trandandan/image/upload/c_thumb,h_48,w_48/${friend.avatar}`,
- medium: `https://res.cloudinary.com/trandandan/image/upload/c_thumb,h_72,w_72/${friend.avatar}`,
- large: `https://res.cloudinary.com/trandandan/image/upload/c_thumb,h_128,w_128/${friend.avatar}`,
+ thumbnail: `https://res.cloudinary.com/trandandan/image/upload/c_thumb,h_48,w_48/${friend.to.avatar}`,
+ medium: `https://res.cloudinary.com/trandandan/image/upload/c_thumb,h_72,w_72/${friend.to.avatar}`,
+ large: `https://res.cloudinary.com/trandandan/image/upload/c_thumb,h_128,w_128/${friend.to.avatar}`,
};
- delete friend.avatar;
return {
- ...friend.to,
+ id: friend.to.userId,
+ firstname: friend.to.firstName,
+ lastname: friend.to.lastName,
avatar,
};
} else {
- friend = friend.from as any;
const avatar: PICTURE = {
- thumbnail: `https://res.cloudinary.com/trandandan/image/upload/c_thumb,h_48,w_48/${friend.avatar}`,
- medium: `https://res.cloudinary.com/trandandan/image/upload/c_thumb,h_72,w_72/${friend.avatar}`,
- large: `https://res.cloudinary.com/trandandan/image/upload/c_thumb,h_128,w_128/${friend.avatar}`,
+ thumbnail: `https://res.cloudinary.com/trandandan/image/upload/c_thumb,h_48,w_48/${friend.from.avatar}`,
+ medium: `https://res.cloudinary.com/trandandan/image/upload/c_thumb,h_72,w_72/${friend.from.avatar}`,
+ large: `https://res.cloudinary.com/trandandan/image/upload/c_thumb,h_128,w_128/${friend.from.avatar}`,
};
- delete friend.avatar;
return {
- ...friend.from,
+ id: friend.from.userId,
+ firstname: friend.from.firstName,
+ lastname: friend.from.lastName,
avatar,
};
}
diff --git a/backend/code/src/gateways/gateways.gateway.ts b/backend/code/src/gateways/gateways.gateway.ts
index ad2fee1..92e264a 100644
--- a/backend/code/src/gateways/gateways.gateway.ts
+++ b/backend/code/src/gateways/gateways.gateway.ts
@@ -47,6 +47,7 @@ export class Gateways implements OnGatewayConnection {
@OnEvent('sendMessages')
sendMessage(message: MessageFormatDto) {
+ console.log("recive msg !")
const chanellname: string = `Romm:${message.roomId}`;
this.server.to(chanellname).emit('message', message);
}
diff --git a/backend/code/src/rooms/rooms.service.ts b/backend/code/src/rooms/rooms.service.ts
index 52b5e12..0413fcc 100644
--- a/backend/code/src/rooms/rooms.service.ts
+++ b/backend/code/src/rooms/rooms.service.ts
@@ -407,9 +407,11 @@ export class RoomsService {
},
},
is_banned: true,
+ is_mueted: true,
},
});
- return members.map((member) => {
+ const filtredmembers = members.filter((member) => !member.is_banned || user.is_admin)
+ return filtredmembers.map((member) => {
if (!member.is_banned || user.is_admin) {
const avatar: PICTURE = {
thumbnail: `https://res.cloudinary.com/trandandan/image/upload/c_thumb,h_48,w_48/${member.user.avatar}`,
@@ -421,6 +423,8 @@ export class RoomsService {
firstname: member.user.firstName,
lastname: member.user.lastName,
avatar: avatar,
+ isBaned: member.is_banned,
+ isMuted: member.is_mueted,
};
}
});
diff --git a/frontend/.DS_Store b/frontend/.DS_Store
index d8a764c..821dbcd 100644
Binary files a/frontend/.DS_Store and b/frontend/.DS_Store differ
diff --git a/frontend/code/package-lock.json b/frontend/code/package-lock.json
index 1a0aa2e..219bfb2 100644
--- a/frontend/code/package-lock.json
+++ b/frontend/code/package-lock.json
@@ -32,6 +32,7 @@
"react-icons": "^4.10.1",
"react-konva": "^18.2.10",
"react-scripts": "^5.0.1",
+ "socket.io-client": "^4.7.2",
"typescript": "^4.9.5",
"web-vitals": "^2.1.4",
"zustand": "^4.4.1"
@@ -4619,6 +4620,11 @@
"@sinonjs/commons": "^1.7.0"
}
},
+ "node_modules/@socket.io/component-emitter": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
+ "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg=="
+ },
"node_modules/@surma/rollup-plugin-off-main-thread": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz",
@@ -8043,6 +8049,46 @@
"node": ">= 0.8"
}
},
+ "node_modules/engine.io-client": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.2.tgz",
+ "integrity": "sha512-CQZqbrpEYnrpGqC07a9dJDz4gePZUgTPMU3NKJPSeQOyw27Tst4Pl3FemKoFGAlHzgZmKjoRmiJvbWfhCXUlIg==",
+ "dependencies": {
+ "@socket.io/component-emitter": "~3.1.0",
+ "debug": "~4.3.1",
+ "engine.io-parser": "~5.2.1",
+ "ws": "~8.11.0",
+ "xmlhttprequest-ssl": "~2.0.0"
+ }
+ },
+ "node_modules/engine.io-client/node_modules/ws": {
+ "version": "8.11.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
+ "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": "^5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/engine.io-parser": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz",
+ "integrity": "sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==",
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
"node_modules/enhanced-resolve": {
"version": "5.15.0",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
@@ -15598,6 +15644,32 @@
"node": ">=8"
}
},
+ "node_modules/socket.io-client": {
+ "version": "4.7.2",
+ "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.2.tgz",
+ "integrity": "sha512-vtA0uD4ibrYD793SOIAwlo8cj6haOeMHrGvwPxJsxH7CeIksqJ+3Zc06RvWTIFgiSqx4A3sOnTXpfAEE2Zyz6w==",
+ "dependencies": {
+ "@socket.io/component-emitter": "~3.1.0",
+ "debug": "~4.3.2",
+ "engine.io-client": "~6.5.2",
+ "socket.io-parser": "~4.2.4"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/socket.io-parser": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
+ "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
+ "dependencies": {
+ "@socket.io/component-emitter": "~3.1.0",
+ "debug": "~4.3.1"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
"node_modules/sockjs": {
"version": "0.3.24",
"resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz",
@@ -17926,6 +17998,14 @@
"resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
"integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="
},
+ "node_modules/xmlhttprequest-ssl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz",
+ "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
"node_modules/y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
diff --git a/frontend/code/package.json b/frontend/code/package.json
index dd76a8a..11c8b68 100644
--- a/frontend/code/package.json
+++ b/frontend/code/package.json
@@ -26,6 +26,7 @@
"react-hot-toast": "^2.4.1",
"react-icons": "^4.10.1",
"react-konva": "^18.2.10",
+ "socket.io-client": "^4.7.2",
"react-scripts": "^5.0.1",
"typescript": "^4.9.5",
"web-vitals": "^2.1.4",
diff --git a/frontend/code/src/Components/Chat/Components/Conversation.tsx b/frontend/code/src/Components/Chat/Components/Conversation.tsx
index 748c479..7e5916a 100644
--- a/frontend/code/src/Components/Chat/Components/Conversation.tsx
+++ b/frontend/code/src/Components/Chat/Components/Conversation.tsx
@@ -1,11 +1,12 @@
import { useEffect, useRef, useState } from "react";
import { ConversationProps } from "..";
-import users, {
+import {
Message,
groupIcon,
chatRooms,
More,
Send,
+ Options,
} from "./tools/Assets";
import { ChatType, useChatStore } from "../Controllers/RoomChatControllers";
@@ -20,6 +21,8 @@ import {
} from "../Services/MessagesServices";
import { useUserStore } from "../../../Stores/stores";
+import { formatTime } from "./tools/utils";
+import { socket } from "../Services/SocketsServices";
export interface ChatPaceHolderProps {
username: string;
@@ -31,46 +34,47 @@ export interface ChatPaceHolderProps {
id: string;
}
-export const CurrentUserMessage = ({ message, time, senderId }: Message) => {
- const [MyUsers] = useState(users);
+export const CurrentUserMessage = ({
+ message,
+ time,
+ senderId,
+ avatar,
+ isFailed,
+}: Message) => {
const currentUser = useUserStore((state) => state);
- const SelectedChat = useChatStore((state) => state.selectedChatID);
- const selectedChatType = useChatStore((state) => state.selectedChatType);
-
- const currentChatMessages = MyUsers.find((user) => user.id === SelectedChat);
-
return senderId === currentUser.id ? (
-
+
{message}
-
- Delivered
+
+ {isFailed ? "Failed" : "Delivered"}
) : (
- {selectedChatType === ChatType.Chat ? (
-
- ) : (
-
user.id === senderId)?.image}
- alt=""
- />
- )}
+
@@ -84,13 +88,11 @@ export const CurrentUserMessage = ({ message, time, senderId }: Message) => {
export const ConversationHeader: React.FC
= ({
onRemoveUserPreview,
}) => {
- const [MyUsers] = useState(users);
-
const LayoutState = useModalStore((state) => state);
const ChatState = useChatStore((state) => state);
const SelectedChat = useChatStore((state) => state.selectedChatID);
- const currentUser = MyUsers.find((user) => user.id === SelectedChat);
+ const currentUser = useChatStore((state) => state.currentDmUser);
const selectedChatType = useChatStore((state) => state.selectedChatType);
const currentRoom = chatRooms.find((room) => room.id === SelectedChat);
@@ -108,11 +110,8 @@ export const ConversationHeader: React.FC = ({
-
@@ -122,7 +121,7 @@ export const ConversationHeader: React.FC
= ({
alt=""
src={
selectedChatType === ChatType.Chat
- ? currentUser?.image
+ ? currentUser?.avatar.large
: groupIcon
}
/>
@@ -130,7 +129,7 @@ export const ConversationHeader: React.FC = ({
{selectedChatType === ChatType.Chat
- ? currentUser?.name
+ ? currentUser?.firstname
: currentRoom?.isOwner
? currentRoom.name + " ♚"
: currentRoom?.name}
@@ -141,7 +140,7 @@ export const ConversationHeader: React.FC = ({
) : (
- {currentRoom?.usersId.length} members
+ {currentRoom?.membersCount} members
)}
@@ -191,7 +190,6 @@ export const ConversationHeader: React.FC = ({
tabIndex={0}
className="p-2 shadow menu dropdown-content z-[1] bg-base-100 rounded-box w-52 absolute right-full "
>
- {/* check if current user is admin or owner to show the settings toast */}
{(currentRoom?.isAdmin === true ||
currentRoom?.isOwner === true) && (
@@ -277,91 +275,158 @@ export const Conversation: React.FC
= ({
const chatState = useChatStore((state) => state);
const messageContainerRef = useRef(null);
- const pushMessage = useChatStore((state) => state.addNewMessage);
- const [CurrentsMessages, setMessages] = useState([]);
+ const scrollToBottom = () => {
+ if (messageContainerRef.current) {
+ const container = messageContainerRef.current;
+ container.scrollTop = container.scrollHeight;
+ }
+ };
+
+ const currentUser = useUserStore((state) => state);
const [inputValue, setInputValue] = useState("");
const [FailToSendMessage, setFail] = useState(false);
+ const [IsLoading, setLoading] = useState(true);
- // Function to handle input changes
const handleInputChange = (e: {
target: { value: React.SetStateAction };
}) => {
setFail(false);
- setInputValue(e.target.value); // Update the input value in state
+ setInputValue(e.target.value);
};
+ useEffect(() => {
+ scrollToBottom();
+ }, [chatState.currentMessages?.length]);
useEffect(() => {
- const fetch = async () =>
+ const handleMessage = (message: {
+ id: string;
+ avatar: {
+ thumbnail: string;
+ medium: string;
+ large: string;
+ };
+ content: string;
+ time: string;
+ roomId: string;
+ authorId: string;
+ }) => {
+ console.log(message);
+ if (message.roomId === chatState.selectedChatID) {
+ const NewMessage: Message = {
+ avatar: message.avatar,
+ senderId: message.authorId,
+ message: message.content,
+ time: message.time,
+ };
+ chatState.pushMessage(NewMessage);
+ scrollToBottom();
+ }
+ };
+ socket.on("message", handleMessage);
+
+ const fetch = async () => {
+ setLoading(true);
getRoomMessagesCall(chatState.selectedChatID, 0, 30).then((res) => {
+ setLoading(false);
if (res?.status !== 200 && res?.status !== 201) {
} else {
const messages: Message[] = [];
res.data.forEach(
(message: {
id: string;
+ avatar: {
+ thumbnail: string;
+ medium: string;
+ large: string;
+ };
content: string;
time: string;
roomId: string;
authorId: string;
}) => {
messages.push({
+ avatar: message.avatar,
senderId: message.authorId,
message: message.content,
time: message.time,
});
}
);
- setMessages(messages);
+ chatState.fillCurrentMessages(messages.reverse());
}
});
+ };
- fetch();
- scrollToBottom();
+ fetch().then(() => {
+ scrollToBottom();
+ });
+ return () => {
+ socket.off("message", handleMessage);
+ };
+ // eslint-disable-next-line
}, [chatState.selectedChatID]);
- const scrollToBottom = () => {
- if (messageContainerRef.current) {
- messageContainerRef.current.scrollTop =
- messageContainerRef.current.scrollHeight;
- }
+ const sendMessage = async () => {
+ if (inputValue.length === 0) return;
+ await sendMessageCall(chatState.selectedChatID, inputValue).then((res) => {
+ setInputValue("");
+ if (res?.status !== 200 && res?.status !== 201) {
+ setFail(true);
+ toast.error("you are not authorized to send messages in this room");
+ chatState.setMessageAsFailed(res?.data.id);
+ } else {
+ // for debug
+ if (chatState.selectedChatType === ChatType.Chat) {
+ const message: Message = {
+ id: res.data.id,
+ avatar: {
+ thumbnail: currentUser.picture.thumbnail,
+ medium: currentUser.picture.medium,
+ large: currentUser.picture.large,
+ },
+ senderId: currentUser.id,
+ message: res.data.content,
+ time: res.data.time,
+ };
+ chatState.pushMessage(message);
+ }
+ }
+ });
};
- const handleKeyPress = (e: KeyboardEvent) => {
+ const handleKeyPress = async (e: KeyboardEvent) => {
if (e.key === "Enter") {
- // validation check
- if (inputValue.length > 0) {
- pushMessage({
- senderId: "2",
- message: inputValue,
- isRead: false,
- time: "10",
- });
- setInputValue("");
- }
+ await sendMessage().then(() => scrollToBottom());
}
- // do stuff
};
return (
- {(CurrentsMessages?.length as number) > 0 ? (
- CurrentsMessages?.map((message) => (
-
- ))
+ {IsLoading === false ? (
+ (chatState.currentMessages?.length as number) > 0 ? (
+ chatState.currentMessages?.map((message) => (
+
+ ))
+ ) : (
+
+ )
) : (
-
+
+
+
)}
@@ -382,30 +447,7 @@ export const Conversation: React.FC
= ({
{
- setInputValue("");
-
- if (inputValue.length > 0) {
- await sendMessageCall(
- chatState.selectedChatID,
- inputValue
- ).then((res) => {
- if (res?.status !== 200 && res?.status !== 201) {
- setFail(true);
- toast.error(
- "you are not authorized to send messages in this room"
- );
- // set the input to red color
- } else {
- // hard coded to change
- pushMessage({
- senderId: "2000",
- message: inputValue,
- isRead: false,
- time: "10",
- });
- }
- });
- }
+ await sendMessage().then(() => scrollToBottom());
}}
className="btn ml-4 btn-square bg-[#8C67F6] hover:bg-green-600"
>
diff --git a/frontend/code/src/Components/Chat/Components/RoomChatHelpers.tsx b/frontend/code/src/Components/Chat/Components/RoomChatHelpers.tsx
index c3e68cd..2c89e64 100644
--- a/frontend/code/src/Components/Chat/Components/RoomChatHelpers.tsx
+++ b/frontend/code/src/Components/Chat/Components/RoomChatHelpers.tsx
@@ -7,16 +7,15 @@ import {
Lock,
More,
NullImage,
- NullUser,
+
RoomMember,
RoomType,
Unlock,
chatRooms,
- check,
+
groupIcon,
} from "./tools/Assets";
-
import {
DeleteRoomCall,
createNewRoomCall,
@@ -31,6 +30,8 @@ import toast from "react-hot-toast";
import { Logo } from "../../Layout/Assets/Logo";
import { useModalStore } from "../Controllers/LayoutControllers";
import { useUserStore } from "../../../Stores/stores";
+import { formatTime } from "./tools/utils";
+import { getBlockedCall, unblockCall } from "../Services/FriendsServices";
interface NullComponentProps {
message: string;
@@ -51,9 +52,14 @@ export const RoomChatPlaceHolder = () => {
const rooms: ChatRoom[] = [];
res.data.forEach(
(room: {
+ countMembers: number;
id: string;
is_admin: boolean;
is_owner: boolean;
+ last_message: {
+ content: string;
+ createdAt: string;
+ };
name: string;
type: string;
}) => {
@@ -65,6 +71,8 @@ export const RoomChatPlaceHolder = () => {
usersId: [],
isOwner: room.is_owner,
isAdmin: room.is_admin,
+ membersCount: room.countMembers,
+ last_message: room.last_message,
});
}
);
@@ -84,7 +92,13 @@ export const RoomChatPlaceHolder = () => {
selectNewChat(room.id)}
- className="message-container flex pt-5 pl-5 pb-5 pr-2 bg-[#1A1C26] items-center hover:bg-[#272932] "
+ className={`message-container flex px-4 py-5 hover:bg-[#272932] items-center ${
+ ChatRoomsState.selectedChatID === room.id
+ ? "bg-[#272932]"
+ : "bg-[#1A1C26]"
+ }
+
+ `}
>
{
- {room?.usersId.length + 1} Members
+ {room?.membersCount} Members
-
+
- {room.messages.length > 0
- ? room.messages[room.messages?.length - 1]?.message
- : "No Messages*"}
+ {room.last_message?.content ?? "No Messages*"}
- {room.messages[room.messages?.length - 1]?.isRead === false ? (
-
-
+ {room.last_message !== null && (
+
+
- ) : (
-
)}
@@ -345,6 +357,145 @@ export const FriendTile = (props: { user: RoomMember }) => {
);
};
+export const BlockedFriendTile = (props: { user: RoomMember }) => {
+ const [IsAdding, setIsAdding] = useState(false);
+ const LayoutState = useModalStore((state) => state);
+ const user = props.user;
+
+ return (
+
+
+
+
+
+
+
+
+ {user?.firstname ?? "user"}
+
+
+
+
+
{
+ setIsAdding(true);
+ await unblockCall(user.id).then((res) => {
+ setIsAdding(false);
+ if (res?.status === 200 || res?.status === 201) {
+ LayoutState.setShowBlockedList(
+ !LayoutState.showBlockedLIstModal
+ );
+ toast.success("User Unblocked Successfully");
+ }
+ });
+ }}
+ className="btn swap swap-rotate bg-purple-500 p-3 rounded-xl text-white hover:bg-blue-400"
+ >
+
+ {IsAdding === true ? "UNBLOCKING..." : "UNBLOCK"}
+
+
+
+
+
+ );
+};
+
+export const BlockedUsersModal = () => {
+ const [currentFriends, setUsers] = useState
([]);
+ const LayoutState = useModalStore((state) => state);
+ const [IsLoading, setIsLoading] = useState(false);
+
+ const [skipCount, setSkipCount] = useState(true);
+
+ useEffect(() => {
+ if (skipCount) setSkipCount(false);
+ if (!skipCount) {
+ const fetchData = async () => {
+ try {
+ setIsLoading(true);
+
+ await getBlockedCall(0, 100).then((res) => {
+ setIsLoading(false);
+ if (res?.status === 200 || res?.status === 201) {
+ const friends: RoomMember[] = [];
+ res.data.forEach(
+ (friend: {
+ userId: string;
+ firstName: string;
+ lastName: string;
+ avatar?: {
+ thumbnail: string;
+ medium: string;
+ large: string;
+ };
+ }) => {
+ friends.push({
+ id: friend.userId,
+ firstname: friend.firstName,
+ lastname: friend.lastName,
+ // to inject it with the real images later
+ avatar: friend.avatar,
+ } as RoomMember);
+ }
+ );
+
+ setUsers(friends);
+ } else {
+ }
+ });
+ } catch (error) {
+ console.error("Error fetching data: ", error);
+ }
+ };
+
+ fetchData();
+ }
+ // eslint-disable-next-line
+ }, [LayoutState.showBlockedLIstModal]);
+ return (
+
+
+
+
+
+ Blocked Friends List
+
+
+
+ {IsLoading === true ? (
+
+
+
+ ) : (
+
+ {currentFriends.length < 1 && (
+
+ )}
+ {currentFriends.map((user) => (
+
+ ))}
+
+ )}
+
+
+
+
+
+ );
+};
+
export const AddUsersModal = () => {
const [currentFriends, setUsers] = useState([]);
const [currentRoomMembers, setRoomMembers] = useState([]);
@@ -381,20 +532,21 @@ export const AddUsersModal = () => {
const friends: RoomMember[] = [];
res.data.forEach(
(friend: {
- userId: string;
- firstName: string;
- LastName: string;
+ id: string;
+ firstname: string;
+ lastname: string;
+ avatar: {
+ thumbnail: string;
+ medium: string;
+ large: string;
+ };
}) => {
friends.push({
- id: friend.userId,
- firstname: friend.firstName,
- lastname: friend.LastName,
+ id: friend.id,
+ firstname: friend.firstname,
+ lastname: friend.lastname,
// to inject it with the real images later
- avatar: {
- thumbnail: NullUser,
- medium: NullUser,
- large: NullUser,
- },
+ avatar: friend.avatar,
} as RoomMember);
}
);
@@ -442,7 +594,7 @@ export const AddUsersModal = () => {
)
)
.map((user) => (
-
+
))}
)}
@@ -476,15 +628,18 @@ export const RoomSettingsModal = () => {
const [RoomName, setName] = useState("");
const [RoomPassword, setPassword] = useState("");
const [LoadingUsers, setLOading] = useState(false);
+ const [IsUpdated, setUpdate] = useState(false);
const handlePasswordChange = (event: {
target: { value: SetStateAction };
}) => {
+ setUpdate(true);
setPassword(event.target.value);
};
const handleChange = (event: {
target: { value: SetStateAction };
}) => {
+ setUpdate(true);
setName(event.target.value);
};
const [selectedOption, setSelectedOption] = useState(RoomType.public);
@@ -518,6 +673,7 @@ export const RoomSettingsModal = () => {
}, [LayoutState.showSettingsModal]);
const resetModalState = () => {
+ setUpdate(false);
setPassword("");
setSelectedOption(currentRoom?.type as RoomType);
setName(currentRoom?.name as string);
@@ -525,7 +681,7 @@ export const RoomSettingsModal = () => {
return (
-
+
{TakingAction === true ? (
@@ -560,7 +716,10 @@ export const RoomSettingsModal = () => {
value="Public"
className="radio checked:bg-purple-500"
checked={selectedOption === RoomType.public}
- onChange={() => setSelectedOption(RoomType.public)}
+ onChange={() => {
+ setUpdate(true);
+ setSelectedOption(RoomType.public);
+ }}
/>
@@ -609,81 +774,59 @@ export const RoomSettingsModal = () => {
) : (
-
+
{currentUsers.length < 2 && (
)}
- {currentUsers
- .filter((user) => user.id !== currentUser.id)
- .map((user) => (
-
-
-
-
-
+
+ {currentUsers
+ .filter((user) => user.id !== currentUser.id)
+ .map((user) => (
+
+
+
+
+
-
- {user?.firstname ?? "user"}
-
-
+
+ {user?.firstname ?? "user"}
+
+
-
-
-
- - {
- setTakeAction(true);
- await takeActionCall(
- selectedChatID as string,
- user.id,
- user.isBaned ? "unban" : "ban"
- ).then((res) => {
- setTakeAction(false);
- if (res?.status === 200 || res?.status === 201) {
- toast.success(res.data.message);
- }
- LayoutState.setShowSettingsModal(
- !LayoutState.showSettingsModal
- );
- });
- }}
+
+
-
- {user.isBaned ? "UnBan" : "Ban"}
-
-
-
- {user.isMuted === false && (
- {
setTakeAction(true);
await takeActionCall(
selectedChatID as string,
user.id,
- "mute"
+ user.isBaned ? "unban" : "ban"
).then((res) => {
setTakeAction(false);
if (
res?.status === 200 ||
res?.status === 201
) {
- toast.success(
- "User Muted For a 5 minutes Successfully"
- );
+ toast.success(res.data.message);
}
LayoutState.setShowSettingsModal(
!LayoutState.showSettingsModal
@@ -691,56 +834,92 @@ export const RoomSettingsModal = () => {
});
}}
>
- mute
+
+ {user.isBaned ? "UnBan" : "Ban"}
+
- )}
-
- - {
- setTakeAction(true);
- await takeActionCall(
- selectedChatID as string,
- user.id,
- "kick"
- ).then((res) => {
- setTakeAction(false);
- LayoutState.setShowSettingsModal(
- !LayoutState.showSettingsModal
- );
-
- if (res?.status === 200 || res?.status === 201) {
- toast.success("User Kicked Successfully");
- }
- });
- }}
- >
- kick
-
- - {
- setTakeAction(true);
- await takeActionCall(
- selectedChatID as string,
- user.id,
- "setAdmin"
- ).then((res) => {
- setTakeAction(false);
- if (res?.status === 200 || res?.status === 201) {
- toast.success(
- "User have been set as Admin Successfully"
+
+ {user.isMuted === false && (
+
- {
+ setTakeAction(true);
+ await takeActionCall(
+ selectedChatID as string,
+ user.id,
+ "mute"
+ ).then((res) => {
+ setTakeAction(false);
+ if (
+ res?.status === 200 ||
+ res?.status === 201
+ ) {
+ toast.success(
+ "User Muted For a 5 minutes Successfully"
+ );
+ }
+ LayoutState.setShowSettingsModal(
+ !LayoutState.showSettingsModal
+ );
+ });
+ }}
+ >
+ mute
+
+ )}
+
+ - {
+ setTakeAction(true);
+ await takeActionCall(
+ selectedChatID as string,
+ user.id,
+ "kick"
+ ).then((res) => {
+ setTakeAction(false);
+ LayoutState.setShowSettingsModal(
+ !LayoutState.showSettingsModal
);
- }
- });
- }}
- >
-
- Set as admin
-
-
-
+
+ if (
+ res?.status === 200 ||
+ res?.status === 201
+ ) {
+ toast.success("User Kicked Successfully");
+ }
+ });
+ }}
+ >
+
kick
+
+
{
+ setTakeAction(true);
+ await takeActionCall(
+ selectedChatID as string,
+ user.id,
+ "setAdmin"
+ ).then((res) => {
+ setTakeAction(false);
+ if (
+ res?.status === 200 ||
+ res?.status === 201
+ ) {
+ toast.success(
+ "User have been set as Admin Successfully"
+ );
+ }
+ });
+ }}
+ >
+
+ Set as admin
+
+
+
+
-
- ))}
+ ))}
+
)}
@@ -776,38 +955,40 @@ export const RoomSettingsModal = () => {
>
{"Close "}
-
{
- console.log(RoomType[selectedOption]);
- if (RoomName !== "" && RoomName.length > 3) {
- setIsLoading(true);
- await updateRoomCall(
- RoomName,
- RoomType[selectedOption],
- currentRoom?.id!,
- selectedOption === RoomType.protected
- ? RoomPassword
- : undefined
- ).then((res) => {
- if (res?.status !== 200 && res?.status !== 201) {
- resetModalState();
- } else {
- toast.success("Room Updated Successfully");
- editRoom(RoomName, selectedOption, currentRoom?.id!);
- resetModalState();
- }
- setIsLoading(false);
- });
- } else {
- toast.error("Room name must be at least 4 characters");
- resetModalState();
- }
- }}
- className="btn hover:bg-purple-500"
- >
- {"Save "}
-
+ {IsUpdated === true && (
+
{
+ console.log(RoomType[selectedOption]);
+ if (RoomName !== "" && RoomName.length > 3) {
+ setIsLoading(true);
+ await updateRoomCall(
+ RoomName,
+ RoomType[selectedOption],
+ currentRoom?.id!,
+ selectedOption === RoomType.protected
+ ? RoomPassword
+ : undefined
+ ).then((res) => {
+ if (res?.status !== 200 && res?.status !== 201) {
+ resetModalState();
+ } else {
+ toast.success("Room Updated Successfully");
+ editRoom(RoomName, selectedOption, currentRoom?.id!);
+ resetModalState();
+ }
+ setIsLoading(false);
+ });
+ } else {
+ toast.error("Room name must be at least 4 characters");
+ resetModalState();
+ }
+ }}
+ className="btn hover:bg-purple-500"
+ >
+ {"Save "}
+
+ )}
diff --git a/frontend/code/src/Components/Chat/Components/UserToUserChat.tsx b/frontend/code/src/Components/Chat/Components/UserToUserChat.tsx
index 4d0a34d..d1a3c5a 100644
--- a/frontend/code/src/Components/Chat/Components/UserToUserChat.tsx
+++ b/frontend/code/src/Components/Chat/Components/UserToUserChat.tsx
@@ -1,13 +1,42 @@
-import { useState } from "react";
+import { useEffect, useState } from "react";
import { UserPreviewCard } from "..";
import { Conversation } from "./Conversation";
+import { useParams } from "react-router-dom";
+import api from "../../../Api/base";
+import { useChatStore } from "../Controllers/RoomChatControllers";
export const UserToUserChat = () => {
+ const params = useParams();
+ console.log(`params : ${params.id} type ${typeof params.id}`);
+
+ const ChatState = useChatStore((state) => state);
const [showUserPreview, setShowUserPreview] = useState(true);
- const handleRemoveUserPreview = () => {
+ useEffect(() => {
+ console.log("selected chat id ", ChatState.selectedChatID);
+ const fetchUser = async () => {
+ try {
+ await api.get(`profile/${params.id}`).then((res) => {
+ console.log(res.data);
+ ChatState.setCurrentDmUser({
+ id: res.data.id,
+ firstname: res.data.name.first,
+ lastname: res.data.name.last,
+ avatar: {
+ thumbnail: res.data.picture.thumbnail,
+ medium: res.data.picture.medium,
+ large: res.data.picture.large,
+ },
+ bio: res.data.bio,
+ });
+ });
+ } catch (error) {}
+ };
+ fetchUser();
+ // eslint-disable-next-line
+ }, [params]);
+ const handleRemoveUserPreview = () => {
setShowUserPreview(!showUserPreview);
-
};
return (
<>
@@ -29,59 +58,54 @@ export const UserToUserChat = () => {
);
};
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+ {/* {user.name} */}
+
+
+
+
+ -
+ Block
+
+ -
+
+ invite for a Pong Game
+
+
+ -
+
+ Show User Info
+
+
+
- {/* {user.name} */}
-
-
-
-
- -
-
- Block
-
-
- -
-
- invite for a Pong Game
-
-
- -
-
- Show User Info
-
-
-
-
- |
-
-
-
-
-
-
+ |
+
+
+
+
;
diff --git a/frontend/code/src/Components/Chat/Components/tools/Assets.tsx b/frontend/code/src/Components/Chat/Components/tools/Assets.tsx
index 541f7ce..596ebd8 100644
--- a/frontend/code/src/Components/Chat/Components/tools/Assets.tsx
+++ b/frontend/code/src/Components/Chat/Components/tools/Assets.tsx
@@ -23,6 +23,8 @@ import Lock from "../../assets/lockIcon.svg";
import Unlock from "../../assets/UnlockIcon.svg";
import ChatGif from "../../assets/chatGif.gif";
import NullUser from "../../assets/User_duotone.svg";
+import exploreIcon from "../../assets/explore_icon.svg";
+import Options from "../../assets/options.svg";
export enum RoomType {
private,
public,
@@ -55,6 +57,8 @@ export {
ChatGif,
NullUser,
owner,
+ exploreIcon,
+ Options,
};
export interface Message {
@@ -63,7 +67,13 @@ export interface Message {
senderId: string;
message: string;
time: string;
+ avatar?: {
+ thumbnail: string;
+ medium: string;
+ large: string;
+ };
isRead?: boolean;
+ isFailed?: boolean;
}
export interface RoomMember {
@@ -75,6 +85,7 @@ export interface RoomMember {
medium: string;
large: string;
};
+ bio?: string;
isBaned?: boolean;
isMuted?: boolean;
}
@@ -88,6 +99,10 @@ export interface ChatRoom {
isAdmin: boolean;
type: RoomType;
membersCount?: number;
+ last_message?: {
+ content?: string;
+ createdAt?: string;
+ };
}
export interface User {
diff --git a/frontend/code/src/Components/Chat/Components/tools/utils.ts b/frontend/code/src/Components/Chat/Components/tools/utils.ts
new file mode 100644
index 0000000..d3b5750
--- /dev/null
+++ b/frontend/code/src/Components/Chat/Components/tools/utils.ts
@@ -0,0 +1,23 @@
+
+export const formatTime = (backendDate: string) => {
+ const currentDate = new Date();
+ const date = new Date(backendDate);
+ const day = date.getDate();
+ const month = date.toLocaleString('en-US', { month: 'short' });
+ const hours = date.getHours();
+ const minutes = date.getMinutes();
+ const ampm = hours >= 12 ? " PM" : " AM";
+ const formattedHours = (hours % 12).toString().padStart(2, "0");
+ const formattedMinutes = minutes.toString().padStart(2, "0");
+
+ if (date.toDateString() === currentDate.toDateString()) {
+ return `${formattedHours}:${formattedMinutes}${ampm}`;
+ } else {
+ return `${day} ${month} ${formattedHours}:${formattedMinutes}${ampm}`;
+ }
+
+
+
+}
+
+
diff --git a/frontend/code/src/Components/Chat/Controllers/LayoutControllers.tsx b/frontend/code/src/Components/Chat/Controllers/LayoutControllers.tsx
index ce032a4..528d3f4 100644
--- a/frontend/code/src/Components/Chat/Controllers/LayoutControllers.tsx
+++ b/frontend/code/src/Components/Chat/Controllers/LayoutControllers.tsx
@@ -5,11 +5,13 @@ export interface ModalState {
showPreviewCard: boolean;
showAddUsersModal: boolean;
showSettingsModal: boolean;
+ showBlockedLIstModal : boolean;
setShowExploreModal: (showExploreModal: boolean) => void;
setShowPreviewCard: (showPreviewCard: boolean) => void;
setShowAddUsersModal: (showAddUsersModal: boolean) => void;
setShowSettingsModal: (showSettingsModal: boolean) => void;
+ setShowBlockedList : (showBlockedLIstModal : boolean) => void;
}
export const useModalStore = create
((set) => ({
@@ -17,6 +19,13 @@ export const useModalStore = create((set) => ({
showPreviewCard: false,
showAddUsersModal: false,
showSettingsModal: false,
+ showBlockedLIstModal : false,
+
+ setShowBlockedList : (showBlockedLIstModal : boolean) => set((state) => {
+ state.showBlockedLIstModal = showBlockedLIstModal;
+ return { ...state };
+ }),
+
setShowSettingsModal: (showSettingsModal: boolean) =>
set((state) => {
diff --git a/frontend/code/src/Components/Chat/Controllers/RoomChatControllers.tsx b/frontend/code/src/Components/Chat/Controllers/RoomChatControllers.tsx
index 8b4731f..d52d5a5 100644
--- a/frontend/code/src/Components/Chat/Controllers/RoomChatControllers.tsx
+++ b/frontend/code/src/Components/Chat/Controllers/RoomChatControllers.tsx
@@ -2,6 +2,7 @@ import { create } from "zustand";
import users, {
ChatRoom,
Message,
+ RoomMember,
RoomType,
chatRooms,
} from "../Components/tools/Assets";
@@ -15,13 +16,19 @@ export interface ChatState {
selectedChatType: ChatType;
selectedChatID: string;
currentMessages: Message[];
+ currentDmUser: RoomMember;
currentRoomMessages: Message[];
isLoading: boolean;
showChatRooms: boolean;
recentRooms: ChatRoom[];
+
+ setCurrentDmUser: (user: RoomMember) => void;
+ setMessageAsFailed: (id: string) => void;
+ pushMessage: (message: Message) => void;
deleteRoom: (id: string) => void;
+ fillCurrentMessages: (messages: Message[]) => void;
fillRecentRooms: (rooms: ChatRoom[]) => void;
setIsLoading: (isLoading: boolean) => void;
selectNewChatID: (id: string) => void;
@@ -40,12 +47,51 @@ export const useChatStore = create()((set) => ({
// UI state
showChatRooms: false,
+ currentDmUser: {
+ id: "1",
+ firstname: "John",
+ lastname: "Doe",
+ avatar: {
+ thumbnail: "",
+ medium: "",
+ large: "",
+ },
+ },
// to fix this
currentMessages: users.find((user) => user.id === "1")?.messages as Message[],
currentRoomMessages: chatRooms.find((room) => room.id === "1")
?.messages as Message[],
+ setCurrentDmUser: (user: RoomMember) =>
+ set((state) => {
+ state.currentDmUser = user;
+ return { ...state };
+ }),
+
+ setMessageAsFailed: (id: string) =>
+ set((state) => {
+ const messageIndex = state.currentMessages.findIndex(
+ (message) => message.id === id
+ );
+ if (messageIndex !== -1) {
+ state.currentMessages[messageIndex].isFailed = true;
+ }
+ return { ...state };
+ }),
+
+ pushMessage: (message: Message) =>
+ set((state) => {
+ state.currentMessages = [...state.currentMessages, message];
+
+ return { ...state };
+ }),
+ fillCurrentMessages: (messages: Message[]) =>
+ set((state) => {
+ state.currentMessages = [...messages];
+ return { ...state };
+ }),
+
deleteRoom: (id: string) =>
set((state) => {
const roomIndex = chatRooms.findIndex((room) => room.id === id);
@@ -65,7 +111,7 @@ export const useChatStore = create()((set) => ({
state.isLoading = isLoading;
return { ...state };
}),
-
+
fillRecentRooms: (rooms: ChatRoom[]) =>
set((state) => {
chatRooms.length = 0;
diff --git a/frontend/code/src/Components/Chat/Services/ChatServices.ts b/frontend/code/src/Components/Chat/Services/ChatServices.ts
index f0dc5a7..632906b 100644
--- a/frontend/code/src/Components/Chat/Services/ChatServices.ts
+++ b/frontend/code/src/Components/Chat/Services/ChatServices.ts
@@ -4,7 +4,8 @@ import api from "../../../Api/base";
export const createNewRoomCall = async (
name: string,
type: string,
- password?: string
+ password?: string,
+ secondMember? : string,
) => {
try {
@@ -12,6 +13,7 @@ export const createNewRoomCall = async (
name: name,
type: type,
password: password,
+ secondMember: secondMember,
});
console.log(response.data);
console.log(response.status);
@@ -199,3 +201,5 @@ export const getFriendsCall = async (
}
+
+
diff --git a/frontend/code/src/Components/Chat/Services/FriendsServices.ts b/frontend/code/src/Components/Chat/Services/FriendsServices.ts
new file mode 100644
index 0000000..68e12bb
--- /dev/null
+++ b/frontend/code/src/Components/Chat/Services/FriendsServices.ts
@@ -0,0 +1,38 @@
+import api from "../../../Api/base";
+
+export const getBlockedCall = async (
+ offset: number,
+ limit: number,
+
+
+ ) => {
+
+ try {
+ const response = await api.get(`/friends/blocklist`,
+ { params: { offset: offset, limit: limit } });
+ console.log("blocked list response");
+ console.log(response.status);
+ console.log(response.data);
+ return response;
+ } catch (e: any) {
+ console.log(e.response.data.message);
+ }
+
+ }
+
+ export const unblockCall = async (
+ friendId : string
+ ) => {
+ try {
+
+ const response = await api.post("/friends/unblock", {
+ friendId :friendId
+ });
+ console.log(response.data);
+ console.log(response.status);
+ return response;
+ } catch (e: any) {
+ console.log(e.response.data.message);
+ }
+ };
+
\ No newline at end of file
diff --git a/frontend/code/src/Components/Chat/Services/MessagesServices.ts b/frontend/code/src/Components/Chat/Services/MessagesServices.ts
index 5dfef84..18a9eeb 100644
--- a/frontend/code/src/Components/Chat/Services/MessagesServices.ts
+++ b/frontend/code/src/Components/Chat/Services/MessagesServices.ts
@@ -2,6 +2,8 @@
import api from "../../../Api/base";
+
+
export const getRoomMessagesCall = async (
id: string,
offset: number,
diff --git a/frontend/code/src/Components/Chat/Services/SocketsServices.ts b/frontend/code/src/Components/Chat/Services/SocketsServices.ts
new file mode 100644
index 0000000..4c1e0d9
--- /dev/null
+++ b/frontend/code/src/Components/Chat/Services/SocketsServices.ts
@@ -0,0 +1,7 @@
+import { io } from 'socket.io-client';
+
+
+export const socket = io("http://localhost:3004", {
+ transports: ['websocket'],
+ withCredentials: true,
+ });
\ No newline at end of file
diff --git a/frontend/code/src/Components/Chat/assets/explore_icon.svg b/frontend/code/src/Components/Chat/assets/explore_icon.svg
new file mode 100644
index 0000000..585f232
--- /dev/null
+++ b/frontend/code/src/Components/Chat/assets/explore_icon.svg
@@ -0,0 +1,10 @@
+
diff --git a/frontend/code/src/Components/Chat/assets/options.svg b/frontend/code/src/Components/Chat/assets/options.svg
new file mode 100644
index 0000000..46fe33b
--- /dev/null
+++ b/frontend/code/src/Components/Chat/assets/options.svg
@@ -0,0 +1,4 @@
+
diff --git a/frontend/code/src/Components/Chat/index.tsx b/frontend/code/src/Components/Chat/index.tsx
index 4dc9721..a2a1e85 100644
--- a/frontend/code/src/Components/Chat/index.tsx
+++ b/frontend/code/src/Components/Chat/index.tsx
@@ -10,7 +10,7 @@ import {
import { useEffect, useState } from "react";
import { Conversation } from "./Components/Conversation";
import { ChatPaceHolderProps } from "./Components/Conversation";
-import users from "./Components/tools/Assets";
+
import React from "react";
import { ChatType, useChatStore } from "./Controllers/RoomChatControllers";
@@ -45,6 +45,7 @@ export const Chat = () => {
const handleRemoveUserPreview = () => {
setShowUserPreview(!showUserPreview);
};
+
return (
<>
@@ -101,11 +102,10 @@ export const UserPreviewCard: React.FC
= ({
}) => {
const [isLoading, setIsLoading] = useState(false);
const [currentUsers, setUsers] = useState([]);
- const [MyUsers] = useState(users);
const LayoutState = useModalStore((state) => state);
const SelectedChat = useChatStore((state) => state.selectedChatID);
- const currentUser = MyUsers.find((user) => user.id === SelectedChat);
+ const currentUser = useChatStore((state) => state.currentDmUser);
const selectedChatType = useChatStore((state) => state.selectedChatType);
const currentRoom = chatRooms.find((room) => room.id === SelectedChat);
@@ -142,7 +142,7 @@ export const UserPreviewCard: React.FC = ({
{selectedChatType === ChatType.Chat ? (
- {currentUser?.name}'s Info
+ {currentUser?.firstname}'s Info
) : (
@@ -164,14 +164,16 @@ export const UserPreviewCard: React.FC = ({
className="w-36 rounded-full "
alt=""
src={
- selectedChatType === ChatType.Chat ? currentUser?.image : groupIcon
+ selectedChatType === ChatType.Chat
+ ? currentUser?.avatar.large
+ : groupIcon
}
/>
{selectedChatType === ChatType.Chat
- ? currentUser?.name
+ ? currentUser?.firstname
: currentRoom?.name}
@@ -183,11 +185,11 @@ export const UserPreviewCard: React.FC = ({
{}
-
{currentUser?.name}'s Bio
+
{currentUser?.firstname}'s Bio
-
- hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+
+ {currentUser?.bio ?? "NO"}
@@ -198,16 +200,16 @@ export const UserPreviewCard: React.FC = ({
{}
{currentRoom?.name}'s Members
-
+
{isLoading === false ? (
<>
{currentUsers.map((user) => (
-
+
diff --git a/frontend/code/src/Components/Layout/index.tsx b/frontend/code/src/Components/Layout/index.tsx
index 225f958..ae9767e 100644
--- a/frontend/code/src/Components/Layout/index.tsx
+++ b/frontend/code/src/Components/Layout/index.tsx
@@ -14,10 +14,11 @@ import { matchRoutes, useLocation } from "react-router-dom";
import { useUserStore } from "../../Stores/stores";
import { useNavigate } from "react-router-dom";
import { FirstLogin } from "../FirstLogin";
-
+import { socket } from "../Chat/Services/SocketsServices";
const routes = [
{ path: "Profile/:id" },
+ { path: "Dm/:id" },
{ path: "Settings" },
{ path: "Home" },
{ path: "Chat" },
@@ -26,13 +27,15 @@ const routes = [
{ path: "Game" },
];
-
const useCurrentPath = () => {
const location = useLocation();
const [{ route }]: any = matchRoutes(routes, location);
return route.path;
};
+function onConnect() {
+ console.log("hello");
+}
export const Layout: FC
= (): JSX.Element => {
const user = useUserStore();
const navigate = useNavigate();
@@ -40,16 +43,18 @@ export const Layout: FC = (): JSX.Element => {
useLayoutEffect(() => {
const log = async () => {
try {
- await user.login();
+ await user.login();
+ } catch (e) {
+ navigate("/");
+ user.logout();
}
- catch(e){
- navigate("/");
- user.logout();
- }
-
-
};
+
+ socket.on("connect", onConnect);
log();
+ return () => {
+ socket.off("connect", onConnect);
+ };
//eslint-disable-next-line
}, []);
const path: string = useCurrentPath();
@@ -62,7 +67,6 @@ export const Layout: FC = (): JSX.Element => {
@@ -80,11 +84,14 @@ export const Layout: FC
= (): JSX.Element => {
-
+
-
+
diff --git a/frontend/code/src/Components/Profile/index.tsx b/frontend/code/src/Components/Profile/index.tsx
index 6bcf321..fa844c4 100644
--- a/frontend/code/src/Components/Profile/index.tsx
+++ b/frontend/code/src/Components/Profile/index.tsx
@@ -1,105 +1,186 @@
-import { Pong } from './assets/Pong'
-import { File } from './assets/File'
-import { Share } from './assets/ShareB'
-import { Message } from './assets/MessageB'
-import { History } from './History'
-import Hero from './assets/Hero.gif'
-import { useState , useEffect } from 'react'
-import { Link, useNavigate, useParams } from 'react-router-dom'
-import { Load } from '../Loading/'
-import Newbie from '../Badges/Newbie.svg'
-import Master from '../Badges/Master.svg'
-import Ultimate from '../Badges/Ultimate.svg'
-import { Edit } from './assets/Edit'
-import { useUserStore } from '../../Stores/stores'
-import dots from './assets/svg/threedots.svg'
-import api from '../../Api/base'
+import { Pong } from "./assets/Pong";
+import { File } from "./assets/File";
+import { Share } from "./assets/ShareB";
+import { Message } from "./assets/MessageB";
+import { History } from "./History";
+import Hero from "./assets/Hero.gif";
+import { useState, useEffect } from "react";
+import { Link, useNavigate, useParams } from "react-router-dom";
+import { Load } from "../Loading/";
+import Newbie from "../Badges/Newbie.svg";
+import Master from "../Badges/Master.svg";
+import Ultimate from "../Badges/Ultimate.svg";
+import { Edit } from "./assets/Edit";
+import { useUserStore } from "../../Stores/stores";
+import dots from "./assets/svg/threedots.svg";
+import api from "../../Api/base";
+import { BlockedUsersModal } from "../Chat/Components/RoomChatHelpers";
+import { useModalStore } from "../Chat/Controllers/LayoutControllers";
+import { createNewRoomCall } from "../Chat/Services/ChatServices";
+import toast from "react-hot-toast";
+import {
+ ChatType,
+ useChatStore,
+} from "../Chat/Controllers/RoomChatControllers";
// import toast from 'react-hot-toast'
-export const Profile = () =>{
- const user = useUserStore();
- const params = useParams();
- const navigate = useNavigate();
- console.log(`params : ${params.id} type ${typeof(params.id)}`)
- const [users, setUsers] = useState
(undefined);
-
- useEffect(() => {
- const fetchUser = async() => {
- try {
- const res = await api.get(`profile/${params.id}`)
- setUsers(res.data)
-
- } catch (error) {
- navigate("/NotFound")
- }
- }
- if (params.id !== user.id || params.id !== "me")
- fetchUser();
- else
- setUsers(user)
- //eslint-disable-next-line
- },[params, user])
- // console.log(users)
- // const handleSendReq = async() => {
- // toast.promise(api.post("friend/add",{friendId:users.id}),{loading:`Sending friend request`,success:`request sent to ${users.name.first}`,error:"could not send friend request"})
- // }
- return (
- <>
-
-
-
-
-
-
-
-
-
-
- {
- users?.picture?.large ?
:
- }
-
-
-
+export const Profile = () => {
+ const user = useUserStore();
+ const params = useParams();
+ const LayoutState = useModalStore((state) => state);
+ const navigate = useNavigate();
+ const ChatState = useChatStore((state) => state);
+ console.log(`params : ${params.id} type ${typeof params.id}`);
+ const [users, setUsers] = useState
(undefined);
+
+ useEffect(() => {
+ const fetchUser = async () => {
+ try {
+ const res = await api.get(`profile/${params.id}`);
+ setUsers(res.data);
+ } catch (error) {
+ navigate("/NotFound");
+ }
+ };
+ if (params.id !== user.id || params.id !== "me") fetchUser();
+ else setUsers(user);
+ //eslint-disable-next-line
+ }, [params, user]);
+ // console.log(users)
+ // const handleSendReq = async() => {
+ // toast.promise(api.post("friend/add",{friendId:users.id}),{loading:`Sending friend request`,success:`request sent to ${users.name.first}`,error:"could not send friend request"})
+ // }
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+ {users?.picture?.large ? (
+
+ ) : (
+
+ )}
-
- {
- users?.name?.first ?
{users?.name?.first} {users.name.last}
:
- }
-
- {users?.bio}
-
-
-
- {
- params.id !== "me" ?
- (<>
- >)
- :
- (
-
- )
+
+
+
+ {users?.name?.first ? (
+
+ {users?.name?.first} {users.name.last}{" "}
+
+ ) : (
+
+ )}{" "}
+
+
+ {users?.bio}
+
+
+
+ {params.id !== "me" ? (
+ <>
+
{
+ await createNewRoomCall(
+ "",
+ "dm",
+ undefined,
+ params.id
+ ).then((res) => {
+ if (res?.status === 200 || res?.status === 201) {
+ ChatState.changeChatType(ChatType.Chat);
+ ChatState.selectNewChatID(res?.data?.id);
+ ChatState.setCurrentDmUser({
+ id: users?.id,
+ firstname: users?.name.first,
+ lastname: users?.name.last,
+ avatar: {
+ thumbnail: users?.picture.thumbnail,
+ medium: users?.picture.medium,
+ large: users?.picture.large,
+ },
+ bio: users?.bio,
+ });
+ navigate(`/Dm/${params.id}`);
+ } else {
+ toast.error(
+ "You Can't Send Message To this User For Now, try Again later"
+ );
}
-
-
-
-
-
-
-
-
- Block
- Send friend request
-
-
-
-
+ });
+ }}
+ >
+
+
+
+ >
+ ) : (
+
+
+
+ )}
-
-
+
+
+
+
+
+
+
+ -
+
Block
+
+ -
+
Send friend request
+
+ - {
+ LayoutState.setShowBlockedList(
+ !LayoutState.showBlockedLIstModal
+ );
+ }}
+ >
+
+
See Blocked List
+
+
+
+
+
+
+
+
+
>
- )
-}
\ No newline at end of file
+ );
+};
diff --git a/frontend/code/src/Routes/index.tsx b/frontend/code/src/Routes/index.tsx
index 6960ede..5c08948 100644
--- a/frontend/code/src/Routes/index.tsx
+++ b/frontend/code/src/Routes/index.tsx
@@ -59,7 +59,7 @@ const router = createBrowserRouter([
},
},
{
- path: "Pure",
+ path: "Dm/:id",
lazy: async () => {
let { UserToUserChat } = await import("../Components/Chat/Components/UserToUserChat");
return { Component: UserToUserChat };
diff --git a/package-lock.json b/package-lock.json
index 53bd024..2110002 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,5 +1,5 @@
{
- "name": "PongGame-WebApp",
+ "name": "PongGame-WebApp-1",
"lockfileVersion": 3,
"requires": true,
"packages": {
@@ -10,7 +10,8 @@
"@material-ui/core": "^4.12.4",
"@mui/material": "^5.14.13",
"lord-icon-element": "^4.1.2",
- "lottie-web": "^5.12.2"
+ "lottie-web": "^5.12.2",
+ "socket.io-client": "^4.7.2"
}
},
"node_modules/@babel/code-frame": {
@@ -662,6 +663,11 @@
"url": "https://opencollective.com/popperjs"
}
},
+ "node_modules/@socket.io/component-emitter": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
+ "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg=="
+ },
"node_modules/@types/parse-json": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
@@ -804,6 +810,22 @@
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
},
+ "node_modules/debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
"node_modules/dom-helpers": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
@@ -813,6 +835,26 @@
"csstype": "^3.0.2"
}
},
+ "node_modules/engine.io-client": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.2.tgz",
+ "integrity": "sha512-CQZqbrpEYnrpGqC07a9dJDz4gePZUgTPMU3NKJPSeQOyw27Tst4Pl3FemKoFGAlHzgZmKjoRmiJvbWfhCXUlIg==",
+ "dependencies": {
+ "@socket.io/component-emitter": "~3.1.0",
+ "debug": "~4.3.1",
+ "engine.io-parser": "~5.2.1",
+ "ws": "~8.11.0",
+ "xmlhttprequest-ssl": "~2.0.0"
+ }
+ },
+ "node_modules/engine.io-parser": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz",
+ "integrity": "sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==",
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
"node_modules/error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@@ -1029,6 +1071,11 @@
"resolved": "https://registry.npmjs.org/lottie-web/-/lottie-web-5.12.2.tgz",
"integrity": "sha512-uvhvYPC8kGPjXT3MyKMrL3JitEAmDMp30lVkuq/590Mw9ok6pWcFCwXJveo0t5uqYw1UREQHofD+jVpdjBv8wg=="
},
+ "node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ },
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -1184,6 +1231,32 @@
"object-assign": "^4.1.1"
}
},
+ "node_modules/socket.io-client": {
+ "version": "4.7.2",
+ "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.2.tgz",
+ "integrity": "sha512-vtA0uD4ibrYD793SOIAwlo8cj6haOeMHrGvwPxJsxH7CeIksqJ+3Zc06RvWTIFgiSqx4A3sOnTXpfAEE2Zyz6w==",
+ "dependencies": {
+ "@socket.io/component-emitter": "~3.1.0",
+ "debug": "~4.3.2",
+ "engine.io-client": "~6.5.2",
+ "socket.io-parser": "~4.2.4"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/socket.io-parser": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
+ "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
+ "dependencies": {
+ "@socket.io/component-emitter": "~3.1.0",
+ "debug": "~4.3.1"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
"node_modules/source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
@@ -1232,6 +1305,34 @@
"node": ">=4"
}
},
+ "node_modules/ws": {
+ "version": "8.11.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
+ "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": "^5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/xmlhttprequest-ssl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz",
+ "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
"node_modules/yaml": {
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
diff --git a/package.json b/package.json
index b34d6ec..2b902a5 100644
--- a/package.json
+++ b/package.json
@@ -5,6 +5,7 @@
"@material-ui/core": "^4.12.4",
"@mui/material": "^5.14.13",
"lord-icon-element": "^4.1.2",
- "lottie-web": "^5.12.2"
+ "lottie-web": "^5.12.2",
+ "socket.io-client": "^4.7.2"
}
}