Skip to content

Commit

Permalink
feat : Video Chat with Chatting
Browse files Browse the repository at this point in the history
  • Loading branch information
Lee-Dongwook committed Oct 21, 2024
1 parent dc495d9 commit 4518276
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 58 deletions.
7 changes: 0 additions & 7 deletions client/src/app/chat/page.tsx

This file was deleted.

7 changes: 0 additions & 7 deletions client/src/app/peer/page.tsx

This file was deleted.

7 changes: 7 additions & 0 deletions client/src/app/videochat/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import VideoChatPage from "@/template/VideoChatPage";

export default function Page({ params }: { params: { roomId: string } }) {
const { roomId } = params;

return <VideoChatPage roomId={roomId} />;
}
116 changes: 75 additions & 41 deletions client/src/components/Chat/index.tsx
Original file line number Diff line number Diff line change
@@ -1,64 +1,98 @@
"use client";

import { useEffect, useState } from "react";
import toast from "react-hot-toast";
import socket from "@/lib/socket";
import React, { useEffect, useState, useRef } from "react";
import { io } from "socket.io-client";
import { Button } from "@/components/ui/button";

const socket = io("http://localhost:4000"); // Signaling 서버 주소

interface ChatProps {
id: string;
roomId: string;
}

export default function Chat({ id }: ChatProps) {
const [message, setMessage] = useState<string>("");
const [messages, setMessages] = useState<string[]>([]);
interface Message {
sender: string;
text: string;
}

const handleSendMessage = () => {
if (message.trim()) {
socket.emit("message", message);
setMessages((prevMessages) => [...prevMessages, `You : ${message}`]);
setMessage("");
}
};
export default function Chat({ roomId }: ChatProps) {
const [message, setMessage] = useState<string>("");
const [messages, setMessages] = useState<Message[]>([]);
const messageEndRef = useRef<HTMLDivElement | null>(null);

const handleReceiveMessage = (receivedMessage: string) => {
toast.success("New message received");
setMessages((prevMessages) => [
...prevMessages,
`Other: ${receivedMessage}`,
]);
const scrollToBottom = () => {
messageEndRef.current?.scrollIntoView({ behavior: "smooth" });
};

useEffect(() => {
socket.on("message", handleReceiveMessage);
socket.on("receive-message", (message: Message) => {
setMessages((prevMessages) => [...prevMessages, message]);
});

socket.emit("join-room", roomId);

return () => {
socket.off("message", handleReceiveMessage);
socket.off("receive-message");
socket.emit("leave-room", roomId);
};
}, [id]);
}, [roomId]);

const sendMessage = () => {
if (message.trim() === "") return;

const newMessage = {
sender: "You",
text: message,
};

socket.emit("send-message", { ...newMessage, roomId });
setMessages((prevMessages) => [...prevMessages, newMessage]);
setMessage("");
scrollToBottom();
};

return (
<div>
<h2 className="text-lg font-bold">Chat</h2>
<div className="bg-gray-100 p-4 h-64 overflow-y-scroll">
<div className="flex flex-col h-full bg-white dark:bg-gray-800 rounded-lg shadow-md">
<div className="flex-1 p-4 overflow-y-auto">
{messages.map((msg, index) => (
<div key={index} className="text-gray-800">
{msg}
<div
key={index}
className={`mb-2 ${
msg.sender === "You" ? "text-right" : "text-left"
}`}
>
<div
className={`inline-block px-3 py-2 rounded-lg ${
msg.sender === "You"
? "bg-blue-500 text-white"
: "bg-gray-300 dark:bg-gray-700 text-gray-800 dark:text-gray-100"
}`}
>
<span className="font-semibold">{msg.sender}: </span>
<span>{msg.text}</span>
</div>
</div>
))}
<div ref={messageEndRef} />
</div>
<div className="p-2 border-t border-gray-300 dark:border-gray-700">
<input
type="text"
value={message}
onChange={(e) => setMessage(e.target.value)}
placeholder="Type a message..."
className="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-gray-800 dark:text-white"
onKeyDown={(e) => {
if (e.key === "Enter") sendMessage();
}}
/>
<Button
onClick={sendMessage}
className="mt-2 w-full bg-blue-500 hover:bg-blue-600 text-white"
>
Send
</Button>
</div>
<input
value={message}
onChange={(e) => setMessage(e.target.value)}
className="border p-2 w-full mt-2"
placeholder="Type a message..."
onKeyDown={(e) => e.key === "Enter" && handleSendMessage()}
/>
<button
onClick={handleSendMessage}
className="bg-blue-500 text-white p-2 mt-2"
>
Send
</button>
</div>
);
}
3 changes: 1 addition & 2 deletions client/src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@ export const mainNavLinks = [
{ title: "Home", url: "/" },
{ title: "My Documents", url: "/document" },
{ title: "Create Document", url: "/document/new" },
{ title: "Real-time Collaboration", url: "/document/realtime" },
{ title: "Peer Call", url: "/peer" },
{ title: "VideoChat", url: "/videochat" },
];
2 changes: 1 addition & 1 deletion client/src/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ export default withAuth(
);

export const config = {
matcher: ["/document/:path*", "/profile", "/setting", "/chat", "/peer"],
matcher: ["/document/:path*", "/profile", "/setting", "/videochat"],
};
27 changes: 27 additions & 0 deletions client/src/template/VideoChatPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"use client";

import React from "react";
import VideoChat from "@/components/VideoChat";
import Chat from "@/components/Chat";

interface VideoChatPageProps {
roomId: string;
}

export default function VideoChatPage({ roomId }: VideoChatPageProps) {
return (
<div className="min-h-screen bg-gray-100 dark:bg-gray-900 p-4">
<div className="flex flex-col lg:flex-row items-start space-y-4 lg:space-y-0 lg:space-x-6 p-4 lg:p-8">
<div className="w-full lg:w-2/3 flex justify-center">
<VideoChat roomId={roomId} />
</div>
</div>
<div className="w-full lg:w-1/3 flex flex-col space-y-4">
<h2 className="text-xl font-bold text-gray-800 dark:text-gray-100">
채팅
</h2>
<Chat roomId={roomId} />
</div>
</div>
);
}

0 comments on commit 4518276

Please sign in to comment.