diff --git a/client/src/components/Chat.js b/client/src/components/Chat.js
new file mode 100644
index 0000000..091154a
--- /dev/null
+++ b/client/src/components/Chat.js
@@ -0,0 +1,75 @@
+// src/components/Chat.js
+import React, { useState, useRef, useCallback, useEffect } from 'react';
+import PropTypes from 'prop-types';
+import toast from 'react-hot-toast';
+import Button from './Button';
+import ChatHandler from '../services/chatHandler';
+import ChatInput from './ChatInput';
+
+
+const Chat = ({ meeting_id, username, socket }) => {
+ const [chatHistory, setChatHistory] = useState([]);
+ const chatHandler = useRef(null);
+
+ const initializeChat = () => {
+ if (!username) {
+ toast.error('Please enter a username before joining a meeting.');
+ return;
+ }
+
+ const errorHandler = (error) => {
+ console.error(error);
+ toast.error(error.message);
+ }
+
+ // Assuming ChatHandler is a utility to handle the chat logic
+ chatHandler.current = new ChatHandler(meeting_id, username, socket, setChatHistory, errorHandler);
+ chatHandler.current.initialize();
+ };
+
+ useEffect(() => {
+ initializeChat();
+ }, [meeting_id, username, socket]);
+
+ const handleSendMessage = useCallback((message) => {
+ if (!message.trim()) {
+ toast.error('Please enter a message before sending.');
+ return;
+ }
+ chatHandler.current.sendMessage(message);
+ setChatHistory(prevHistory => [...prevHistory, { sender: username, text: message }]);
+ }, [username]);
+
+ const getProfilePicture = (name) => {
+ return `https://ui-avatars.com/api/?name=${encodeURIComponent(name)}&background=random`;
+ };
+
+ return (
+
+
Chat
+
+ {chatHistory.map((msg, index) => (
+
+
+
+ {msg.sender}: {msg.text}
+
+
+ ))}
+
+
+
+ );
+};
+
+Chat.propTypes = {
+ meeting_id: PropTypes.string.isRequired,
+ username: PropTypes.string.isRequired,
+ socket: PropTypes.object.isRequired,
+};
+
+export default Chat;
diff --git a/client/src/components/ChatInput.js b/client/src/components/ChatInput.js
index f5dc353..6c9beb3 100644
--- a/client/src/components/ChatInput.js
+++ b/client/src/components/ChatInput.js
@@ -2,35 +2,33 @@ import React, { useRef } from 'react';
import Button from '../components/Button';
import PropTypes from 'prop-types';
-const ChatInput = ({ onSend }) => {
+const ChatInputSection = ({ onSend }) => {
const inputRef = useRef();
const handleSendMessage = (e) => {
- e.preventDefault();
+ e.preventDefault(); // Prevent the form from causing a page reload
const message = inputRef.current.value.trim();
if (message) {
onSend(message);
inputRef.current.value = ''; // Clear the input after sending
- } else {
- console.error('Message cannot be empty');
}
};
return (
-
+
+
+
);
};
-ChatInput.propTypes = {
+ChatInputSection.propTypes = {
onSend: PropTypes.func.isRequired,
};
-export default ChatInput;
+export default ChatInputSection;
diff --git a/client/src/pages/MeetingPage.js b/client/src/pages/MeetingPage.js
index 55f16d3..f1bc1e8 100644
--- a/client/src/pages/MeetingPage.js
+++ b/client/src/pages/MeetingPage.js
@@ -1,9 +1,8 @@
import React, { useState, useEffect, useRef, useCallback } from 'react';
import { useParams, useLocation, useNavigate } from 'react-router-dom';
import io from 'socket.io-client';
-import ChatHandler from '../services/chatHandler';
import RTCHandler from '../services/rtcHandler';
-import ChatInput from '../components/ChatInput';
+import Chat from '../components/Chat';
import Button from '../components/Button';
import toast, { Toaster } from 'react-hot-toast';
@@ -22,9 +21,6 @@ const MeetingPage = () => {
const [isMuted, setIsMuted] = useState(false);
const [isVideoOff, setIsVideoOff] = useState(false);
- const chatHandler = useRef(null);
- const [chatHistory, setChatHistory] = useState([]);
-
const initializeMeeting = () => {
if (!username) {
toast.error('Please enter a username before joining a meeting.');
@@ -47,10 +43,8 @@ const MeetingPage = () => {
console.error(error);
navigate('/');
toast.error(error.message);
- }
+ };
- chatHandler.current = new ChatHandler(meeting_id, username, socketRef.current, setChatHistory, errorHandler);
- chatHandler.current.initialize();
rtcHandler.current = new RTCHandler(meeting_id, username, socketRef.current, setPeers, errorHandler);
rtcHandler.current.initialize();
};
@@ -61,16 +55,14 @@ const MeetingPage = () => {
return () => {
rtcHandler.current.cleanup();
socketRef.current.disconnect();
- }
+ };
}, []);
const toggleMute = () => {
setIsMuted(prevState => {
const newMutedState = !prevState;
- // Mute or unmute the audio track in the local stream
if (rtcHandler.current && rtcHandler.current.localStream) {
rtcHandler.current.localStream.getAudioTracks().forEach(track => {
- console.log(track);
track.enabled = !newMutedState;
});
}
@@ -81,10 +73,8 @@ const MeetingPage = () => {
const toggleVideo = () => {
setIsVideoOff(prevState => {
const newVideoState = !prevState;
- // Turn on or off the video track in the local stream
if (rtcHandler.current && rtcHandler.current.localStream) {
rtcHandler.current.localStream.getVideoTracks().forEach(track => {
- console.log(track);
track.enabled = !newVideoState;
});
}
@@ -92,24 +82,6 @@ const MeetingPage = () => {
});
};
- const handleSendMessage = useCallback((message) => {
- if (!message.trim()) {
- toast.error('Please enter a message before sending.');
- return;
- }
- chatHandler.current.sendMessage(message);
- setChatHistory(prevHistory => [...prevHistory, { sender: username, text: message }]);
- }, [username]);
-
-
- const getProfilePicture = (name) => {
- return `https://ui-avatars.com/api/?name=${encodeURIComponent(name)}&background=random`;
- };
-
- if (!username || !rtcHandler.current) {
- return null;
- }
-
const VideoElement = React.memo(({ stream, muted, peerName }) => {
const videoRef = useRef();
@@ -121,29 +93,15 @@ const MeetingPage = () => {
return (
);
});
- const ChatMessages = React.memo(({ chatHistory }) => (
-
- {chatHistory.map((msg, index) => (
-
-
-
- {msg.sender}: {msg.text}
-
-
- ))}
-
- ));
-
+ if (!username || !rtcHandler.current) {
+ return null;
+ }
return (
@@ -154,23 +112,21 @@ const MeetingPage = () => {
-
+ {rtcHandler.current.localStream && (
+
+ )}
{Object.entries(peers).map(([peerUsername, peer]) => (
peerUsername !== username && (
-
)
))}
-
-
Chat
-
-
-
+