From 17af48fe2ca9073094fd9d5c3b45635af1bcf48c Mon Sep 17 00:00:00 2001 From: Ishaan Dey Date: Fri, 3 May 2024 14:58:56 -0700 Subject: [PATCH] working basic live collab --- backend/server/dist/index.js | 3 +- backend/server/src/index.ts | 5 ++- frontend/app/globals.css | 35 +++++++++++++++++++ frontend/components/editor/index.tsx | 37 +++++++++++---------- frontend/components/editor/live/cursors.tsx | 1 + frontend/components/editor/navbar/index.tsx | 3 ++ 6 files changed, 65 insertions(+), 19 deletions(-) diff --git a/backend/server/dist/index.js b/backend/server/dist/index.js index 5ff97cb..2134505 100644 --- a/backend/server/dist/index.js +++ b/backend/server/dist/index.js @@ -57,7 +57,8 @@ io.use((socket, next) => __awaiter(void 0, void 0, void 0, function* () { return; } const sandbox = dbUserJSON.sandbox.find((s) => s.id === sandboxId); - if (!sandbox) { + const sharedSandboxes = dbUserJSON.usersToSandboxes.find((uts) => uts.sandboxId === sandboxId); + if (!sandbox && !sharedSandboxes) { console.log("Invalid credentials."); next(new Error("Invalid credentials.")); return; diff --git a/backend/server/src/index.ts b/backend/server/src/index.ts index 835f27b..039a261 100644 --- a/backend/server/src/index.ts +++ b/backend/server/src/index.ts @@ -63,8 +63,11 @@ io.use(async (socket, next) => { } const sandbox = dbUserJSON.sandbox.find((s) => s.id === sandboxId) + const sharedSandboxes = dbUserJSON.usersToSandboxes.find( + (uts) => uts.sandboxId === sandboxId + ) - if (!sandbox) { + if (!sandbox && !sharedSandboxes) { console.log("Invalid credentials.") next(new Error("Invalid credentials.")) return diff --git a/frontend/app/globals.css b/frontend/app/globals.css index 5d2838d..abbbb13 100644 --- a/frontend/app/globals.css +++ b/frontend/app/globals.css @@ -106,4 +106,39 @@ padding: 2px 4px; border-radius: 4px; margin-left: 56px; +} + +.yRemoteSelection { + opacity: 0.5; + background-color: var(--user-color); + margin-right: -1px; +} + +/* Cursor caret */ +.yRemoteSelectionHead { + position: absolute; + box-sizing: border-box; + height: 100%; + border-left: 2px solid var(--user-color); +} + +/* Cursor name */ +.yRemoteSelectionHead::after { + position: absolute; + top: -1.4em; + left: -2px; + padding: 2px 6px; + background: var(--user-color); + color: #fff; + border: 0; + border-radius: 6px; + border-bottom-left-radius: 0; + line-height: normal; + white-space: nowrap; + font-size: 14px; + font-style: normal; + font-weight: 600; + pointer-events: none; + user-select: none; + z-index: 1000; } \ No newline at end of file diff --git a/frontend/components/editor/index.tsx b/frontend/components/editor/index.tsx index 72f5fad..5f51dd4 100644 --- a/frontend/components/editor/index.tsx +++ b/frontend/components/editor/index.tsx @@ -42,7 +42,6 @@ import { TFile, TFileData, TFolder, TTab } from "./sidebar/types" import { User } from "@/lib/types" import { processFileType, validateName } from "@/lib/utils" import { Cursors } from "./live/cursors" -import { Avatars } from "./live/avatars" export default function CodeEditor({ userData, @@ -271,26 +270,31 @@ export default function CodeEditor({ }) useEffect(() => { - if (!editorRef.current) return + let yProvider: any + let yDoc: Y.Doc + let binding: MonacoBinding - const yDoc = new Y.Doc() - const yText = yDoc.getText("monaco") - const yProvider: any = new LiveblocksProvider(room, yDoc) - setProvider(yProvider) + if (editorRef.current) { + yDoc = new Y.Doc() + const yText = yDoc.getText("monaco") + yProvider = new LiveblocksProvider(room, yDoc) + setProvider(yProvider) - const binding = new MonacoBinding( - yText, - editorRef.current.getModel() as monaco.editor.ITextModel, - new Set([editorRef.current]), - yProvider.awareness as Awareness - ) + // Attach Yjs to Monaco + binding = new MonacoBinding( + yText, + editorRef.current.getModel() as monaco.editor.ITextModel, + new Set([editorRef.current]), + yProvider.awareness as Awareness + ) + } return () => { - yDoc.destroy() - yProvider.destroy() - binding.destroy() + yDoc?.destroy() + yProvider?.destroy() + binding?.destroy() } - }, [editorRef, room]) + }, [editorRef.current, room]) // connection/disconnection effect + resizeobserver useEffect(() => { @@ -490,7 +494,6 @@ export default function CodeEditor({ {tab.name} ))} -
+ +