diff --git a/backend/src/chat/chat.gateway.ts b/backend/src/chat/chat.gateway.ts index 11ddb812..2ec61a57 100644 --- a/backend/src/chat/chat.gateway.ts +++ b/backend/src/chat/chat.gateway.ts @@ -144,7 +144,6 @@ export class ChatGateway @SubscribeMessage('listChats') async listChats(@ConnectedSocket() client: Socket) { const chats = await this.chatService.listChats(); - // TODO: do not display PRIVATE CHATS client.emit('listChats', chats); } @@ -180,6 +179,18 @@ export class ChatGateway client.emit('error', { error: 'Protected chat must have password' }); return; } + if (chatType === 'PRIVATE') { + // check if a chat with that name already exists + const createdChat = await this.chatService.getChatByName(chatName); + if (createdChat) { + client.join(`chat:${createdChat.id}`); + client.emit('joinChat', { + message: `You joined chat ${createdChat.id}`, + }); + client.emit('createChat', createdChat); + return; + } + } const createdChat = await this.chatService.createChat( login, chatName, diff --git a/backend/src/chat/chat.service.ts b/backend/src/chat/chat.service.ts index b07d2c50..061df210 100644 --- a/backend/src/chat/chat.service.ts +++ b/backend/src/chat/chat.service.ts @@ -665,4 +665,17 @@ export class ChatService { return isPasswordValid; } + + async getChatByName(name: string): Promise { + try { + const chat = await this.prisma.chat.findFirst({ + where: { + name, + }, + }); + return chat; + } catch (error) { + return null; + } + } } diff --git a/frontend/src/components/Chat/ChannelCard.tsx b/frontend/src/components/Chat/ChannelCard.tsx index eed8e213..affe1e00 100644 --- a/frontend/src/components/Chat/ChannelCard.tsx +++ b/frontend/src/components/Chat/ChannelCard.tsx @@ -1,4 +1,4 @@ -import { ArrowRight, Crown, Lock, TrashSimple } from "@phosphor-icons/react"; +import { ArrowRight, Crown, EnvelopeSimple, Lock, TrashSimple } from "@phosphor-icons/react"; import { useContext } from "react"; import { Chat, ChatContext } from "@/contexts/ChatContext"; import chatService from "@/services/chatClient"; @@ -22,15 +22,15 @@ export default function ChannelCard({ chat }: ChannelCardProps) { }; return ( - // TODO: add user context for chat owner
handleOpenChannel()}> {chat.name}
- {chat.chatType === 'PROTECTED' && } - {chat.owner === user.login && } + {chat.owner === user.login && } + {chat.chatType === 'PROTECTED' && } + {chat.chatType === 'PRIVATE' && }
@@ -38,12 +38,14 @@ export default function ChannelCard({ chat }: ChannelCardProps) { handleDeleteChannel()} /> )} handleOpenChannel()} />
diff --git a/frontend/src/components/Chat/ChatUsersChannelPopOver.tsx b/frontend/src/components/Chat/ChatUsersChannelPopOver.tsx index 28d38613..2c20c079 100644 --- a/frontend/src/components/Chat/ChatUsersChannelPopOver.tsx +++ b/frontend/src/components/Chat/ChatUsersChannelPopOver.tsx @@ -164,7 +164,6 @@ export default function ChatUsersChannelPopOver({ {...attributes.popper} >
- {/*TODO: Find a way to remove this validation without breaking the database seed*/} {myUser && (
- ) /*TODO: Make this command responsive */ + ) } { user.role !== "MEMBER" && ( @@ -248,7 +247,7 @@ export default function ChatUsersChannelPopOver({ aria-label="Channel Admin" alt="Channel Admin" /> - ) /*TODO: Make this command responsive */ + ) } { myUser && @@ -262,7 +261,7 @@ export default function ChatUsersChannelPopOver({ alt="Mute user" onClick={() => handleMuteUser(user)} /> - ) /*TODO: Make this command responsive */ + ) } { myUser && @@ -276,7 +275,7 @@ export default function ChatUsersChannelPopOver({ alt="Unmute user" onClick={() => handleUnmuteUser(user)} /> - ) /*TODO: Make this command responsive */ + ) } { myUser && @@ -289,7 +288,7 @@ export default function ChatUsersChannelPopOver({ alt="Ban user" onClick={() => handleBanUser(user)} /> - ) /*TODO: Make this command responsive */ + ) } { myUser && @@ -302,7 +301,7 @@ export default function ChatUsersChannelPopOver({ alt="Kick user" onClick={() => handleKickUser(user)} /> - ) /*TODO: Make this command responsive */ + ) }
diff --git a/frontend/src/components/Chat/FriendCard.tsx b/frontend/src/components/Chat/FriendCard.tsx index 4997d6b6..d6d7e1f4 100644 --- a/frontend/src/components/Chat/FriendCard.tsx +++ b/frontend/src/components/Chat/FriendCard.tsx @@ -1,11 +1,14 @@ import { api } from "@/services/apiClient"; import { queryClient } from "@/services/queryClient"; import { UserStatus } from "@/types/user"; -import { EnvelopeSimple, Sword, UserMinus } from "@phosphor-icons/react"; +import { EnvelopeSimple, UserMinus } from "@phosphor-icons/react"; +import chatService from "@/services/chatClient"; import { useMutation } from "@tanstack/react-query"; import Link from "next/link"; import toast from "react-hot-toast"; import InviteToGame from "../InviteToGame"; +import { ChatContext } from "@/contexts/ChatContext"; +import { useContext } from "react"; type FriendCardProps = { displayName: string; @@ -18,6 +21,8 @@ export default function FriendCard({ id, status, }: FriendCardProps) { + const { user } = useContext(ChatContext); + const deleteFriendMutation = useMutation({ mutationFn: (friendData: any) => { return api.delete("/friends", { @@ -37,6 +42,15 @@ export default function FriendCard({ deleteFriendMutation.mutate({ friend_id: id }); }; + const handleOpenDirectMessage = () => { + const chatName = `${displayName} - ${user.displayName}`; + chatService.socket?.emit("createChat", { + chatName, + chatType: "PRIVATE", + password: "", + }); + }; + return (
@@ -53,7 +67,11 @@ export default function FriendCard({ >
- + chat.chatType !== "PRIVATE" + ); + return (
@@ -32,8 +37,7 @@ export function ListChannels({ handleShowCreateChannel }: ListChannelsProps) { className="flex flex-col flex-1 max-h-[80vh] bg-black42-300 overflow-y-scroll overscroll-contain my-4 scrollbar scrollbar-w-1 scrollbar-rounded-lg scrollbar-thumb-rounded-lg scrollbar-thumb-black42-100 scrollbar-track-black42-300" > - {chatList?.map((channel: Chat) => ( - // TODO: add user context for chat owner + {publicChats?.map((channel: Chat) => ( ))}
diff --git a/frontend/src/components/Chat/OpenChannel.tsx b/frontend/src/components/Chat/OpenChannel.tsx index a908db99..0ad183aa 100644 --- a/frontend/src/components/Chat/OpenChannel.tsx +++ b/frontend/src/components/Chat/OpenChannel.tsx @@ -17,6 +17,10 @@ interface Message { userId: string; } +type FormInputs = { + password: string; +}; + export function OpenChannel() { const { selectedChat, @@ -68,6 +72,7 @@ export function OpenChannel() { const handleSendMessage = () => { if (myUser && myUser.status === "MUTED") return; + chatService.socket?.emit("message", { chatId: selectedChat.id, content: message, @@ -83,10 +88,6 @@ export function OpenChannel() { }, 100); }; - type FormInputs = { - password: string; - }; - const { register, setError, @@ -159,14 +160,22 @@ export function OpenChannel() {
- -
- ({numberOfUsersInChat}) - -
-
+ {selectedChat.chatType !== "PRIVATE" && ( + +
+ ({numberOfUsersInChat}) + +
+
+ )}
-

{selectedChat.name}

+

+ {selectedChat.chatType === "PRIVATE" + ? `DM: ${selectedChat.name + .split(" - ") + .filter((name) => name !== user.displayName)}` + : selectedChat.name} +

(