diff --git a/client/package-lock.json b/client/package-lock.json index ed5c80d..fae9e89 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -17,6 +17,7 @@ "@fortawesome/free-solid-svg-icons": "^6.5.1", "@fortawesome/react-fontawesome": "^0.2.0", "@google/generative-ai": "^0.21.0", + "@monaco-editor/react": "^4.6.0", "@mui/icons-material": "^5.15.12", "@mui/material": "^5.16.7", "@splinetool/react-spline": "^2.2.6", @@ -34,6 +35,7 @@ "lucide-react": "^0.447.0", "match-sorter": "^6.3.4", "mdb-react-ui-kit": "^7.2.0", + "monaco-editor": "^0.52.0", "open-source": "file:", "otp-input-react": "^0.3.0", "prop-types": "^15.8.1", @@ -51,7 +53,7 @@ "react-toggle": "^4.1.3", "react-top-loading-bar": "^2.3.1", "socket.io": "^4.7.5", - "socket.io-client": "^4.7.5", + "socket.io-client": "^4.8.1", "sort-by": "^0.0.2", "yup": "^1.4.0" }, @@ -1392,6 +1394,32 @@ "@lit-labs/ssr-dom-shim": "^1.0.0" } }, + "node_modules/@monaco-editor/loader": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.4.0.tgz", + "integrity": "sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==", + "license": "MIT", + "dependencies": { + "state-local": "^1.0.6" + }, + "peerDependencies": { + "monaco-editor": ">= 0.21.0 < 1" + } + }, + "node_modules/@monaco-editor/react": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.6.0.tgz", + "integrity": "sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==", + "license": "MIT", + "dependencies": { + "@monaco-editor/loader": "^1.4.0" + }, + "peerDependencies": { + "monaco-editor": ">= 0.25.0 < 1", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/@mui/core-downloads-tracker": { "version": "5.16.7", "license": "MIT", @@ -5123,6 +5151,12 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/monaco-editor": { + "version": "0.52.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.52.0.tgz", + "integrity": "sha512-OeWhNpABLCeTqubfqLMXGsqf6OmPU6pHM85kF3dhy6kq5hnhuVS1p3VrEW/XhWHc71P2tHyS5JFySD8mgs1crw==", + "license": "MIT" + }, "node_modules/ms": { "version": "2.1.3", "license": "MIT" @@ -7096,6 +7130,8 @@ }, "node_modules/socket.io-client": { "version": "4.8.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.1.tgz", + "integrity": "sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==", "license": "MIT", "dependencies": { "@socket.io/component-emitter": "~3.1.0", @@ -7137,6 +7173,12 @@ "node": ">=0.10.0" } }, + "node_modules/state-local": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz", + "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==", + "license": "MIT" + }, "node_modules/string-convert": { "version": "0.2.1", "license": "MIT" diff --git a/client/package.json b/client/package.json index 4fa13b3..ee7f6ff 100644 --- a/client/package.json +++ b/client/package.json @@ -19,6 +19,7 @@ "@fortawesome/free-solid-svg-icons": "^6.5.1", "@fortawesome/react-fontawesome": "^0.2.0", "@google/generative-ai": "^0.21.0", + "@monaco-editor/react": "^4.6.0", "@mui/icons-material": "^5.15.12", "@mui/material": "^5.16.7", "@splinetool/react-spline": "^2.2.6", @@ -36,6 +37,7 @@ "lucide-react": "^0.447.0", "match-sorter": "^6.3.4", "mdb-react-ui-kit": "^7.2.0", + "monaco-editor": "^0.52.0", "open-source": "file:", "otp-input-react": "^0.3.0", "prop-types": "^15.8.1", @@ -53,7 +55,7 @@ "react-toggle": "^4.1.3", "react-top-loading-bar": "^2.3.1", "socket.io": "^4.7.5", - "socket.io-client": "^4.7.5", + "socket.io-client": "^4.8.1", "sort-by": "^0.0.2", "yup": "^1.4.0" }, diff --git a/client/src/App.jsx b/client/src/App.jsx index 5d7cd7d..951cf40 100644 --- a/client/src/App.jsx +++ b/client/src/App.jsx @@ -43,6 +43,7 @@ import Cursor from './component/Cursor'; import AOS from 'aos'; import 'aos/dist/aos.css'; +import Collab from "./component/Collab"; import Ai from "./component/AI"; import FAQ from "./component/FAQ"; // Import the FAQ component @@ -144,6 +145,8 @@ function App() { } /> } /> } /> + } /> + {/* } /> */} } /> {/* } /> */} } /> diff --git a/client/src/component/Collab.jsx b/client/src/component/Collab.jsx new file mode 100644 index 0000000..686923a --- /dev/null +++ b/client/src/component/Collab.jsx @@ -0,0 +1,54 @@ +import { useEffect, useRef, useState } from "react"; +import { io } from "socket.io-client"; +import MonacoEditor from "@monaco-editor/react"; + +// Adjust this to your Socket.IO server URL +const SOCKET_SERVER_URL = "http://localhost:5000"; + +const Collab = () => { + const [code, setCode] = useState("// Start coding collaboratively!\n"); + const [socket, setSocket] = useState(null); + const editorRef = useRef(null); + + // Initialize the Socket.IO client + useEffect(() => { + const newSocket = io(SOCKET_SERVER_URL); + setSocket(newSocket); + + newSocket.on("code_update", (newCode) => { + setCode(newCode); + }); + + return () => { + newSocket.disconnect(); + }; + }, []); + + // Handle code change in the editor + const handleCodeChange = (newCode) => { + setCode(newCode); + if (socket) { + socket.emit("code_change", newCode); + } + }; + + // Attach the editor instance to ref for further usage + const handleEditorDidMount = (editor) => { + editorRef.current = editor; + }; + + return ( +
+ +
+ ); +}; + +export default Collab; diff --git a/server/index.js b/server/index.js index 76c4d01..560a7fc 100644 --- a/server/index.js +++ b/server/index.js @@ -50,12 +50,17 @@ app.use("/api/contact", require("./routes/contact")); // Socket.io connection handling const users = {}; +let currentCode = '// Start coding collaboratively!\n'; + io.on("connection", (socket) => { socket.on("new-user-joined", (name) => { users[socket.id] = name; socket.broadcast.emit("user-joined", name); }); + // Send the current code to the newly connected user + socket.emit('code_update', currentCode); + socket.on("send", (message) => { socket.broadcast.emit("receive", { message: message, @@ -63,6 +68,12 @@ io.on("connection", (socket) => { }); }); + // Listen for code changes and broadcast them + socket.on('code_change', (newCode) => { + currentCode = newCode; + socket.broadcast.emit('code_update', newCode); + }); + socket.on("disconnect", () => { if (users[socket.id]) { socket.broadcast.emit("left", users[socket.id]);