From 536c847375a406571a2d7f5fb3f708f4e80c4a6d Mon Sep 17 00:00:00 2001 From: Artemy Date: Tue, 4 Apr 2023 20:10:41 +0300 Subject: [PATCH] feat: collaborative editing --- index.js | 25 +++++++++++++++++ src/App.jsx | 2 -- src/localisation/en.js | 3 ++ src/localisation/ru.js | 3 ++ src/pages/create.jsx | 64 ++++++++++++++++++++++++++++++++++++++++++ src/pages/settings.jsx | 11 ++++++++ 6 files changed, 106 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index d86e3c7..a93607d 100644 --- a/index.js +++ b/index.js @@ -17,6 +17,31 @@ if (!fs.existsSync("./notes")) { fs.mkdirSync("./notes"); } +io.on("connection", (socket) => { + socket.on("nameChanged", ({ name, room }) => { + socket.to(room).emit("nameChanged", { + name, + }); + }); + + socket.on("textChanged", ({ text, room }) => { + socket.to(room).emit("textChanged", { + text, + }); + }); + + socket.on("joinRoom", (room) => { + let rooms = Array.from(io.sockets.adapter.sids.get(socket.id)); + + for (let room of rooms) { + if (socket.id != room) { + socket.leave(room); + } + } + socket.join(room); + }); +}); + app.use(bodyParser.json()); app.post("/publish", function (req, res) { diff --git a/src/App.jsx b/src/App.jsx index e690f0d..0c07476 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -12,7 +12,6 @@ import PubNoteSafe from "./pages/pubNoteSafe"; import RenderMarkdown from "./components/markdown"; import socket from "./components/socket"; import Settings from "./pages/settings"; -import Chat from "./pages/chat"; import Locales from "./localisation/main"; import { useState } from "react"; @@ -55,7 +54,6 @@ function App() { } /> } /> } /> - } /> window.socketTimeout) { + socket.emit("nameChanged", { + name: e.target.value, + room: settings.CollabEditPassword, + }); + window.lastSocketUpdate = Date.now(); + } +} + +function textUpdate(e) { + if (Date.now() - window.lastSocketUpdate > window.socketTimeout) { + socket.emit("textChanged", { + text: e.target.value, + room: settings.CollabEditPassword, + }); + window.lastSocketUpdate = Date.now(); + } +} + function CreateNote() { const [preview, setPreview] = useState(false); const [publicState, setPublicState] = useState(settings.publicNote); @@ -42,6 +62,32 @@ function CreateNote() { md = md.value.trim(); localStorage.setItem("NoteText", md); + + if (settings.CollabEdit === true) { + socket.emit("textChanged", { + text: md, + room: settings.CollabEditPassword, + }); + } + } + + if (settings.CollabEdit === true) { + if (!window.alreadyConnected) { + socket.emit("joinRoom", settings.CollabEditPassword); + window.alreadyConnected = true; + window.lastSocketUpdate = Date.now(); + window.socketTimeout = 100; + } + + socket.on("textChanged", (data) => { + setText(data.text); + localStorage.setItem("NoteText", data.text); + }); + + socket.on("nameChanged", (data) => { + setName(data.name); + localStorage.setItem("NoteName", data.name); + }); } return ( @@ -73,6 +119,13 @@ function CreateNote() { onChange={(e) => { setName(e.target.value); localStorage.setItem("NoteName", e.target.value); + + if (settings.CollabEdit === true) { + nameUpdate(e); + setTimeout(() => { + nameUpdate(e); + }, window.socketTimeout); + } }} /> @@ -148,6 +208,10 @@ function CreateNote() { }} /> )} + )} diff --git a/src/pages/settings.jsx b/src/pages/settings.jsx index 633f463..0d3a9ae 100644 --- a/src/pages/settings.jsx +++ b/src/pages/settings.jsx @@ -51,6 +51,17 @@ function Settings() { label={locals.AdditionalFeatures} settingName="additionalFeatures" /> + + + + { + window.alreadyConnected = false; + }} + />