working basic live collab

This commit is contained in:
Ishaan Dey 2024-05-03 14:58:56 -07:00
parent a18bcf9c14
commit 17af48fe2c
6 changed files with 65 additions and 19 deletions

View File

@ -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;

View File

@ -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

View File

@ -107,3 +107,38 @@
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;
}

View File

@ -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()
if (editorRef.current) {
yDoc = new Y.Doc()
const yText = yDoc.getText("monaco")
const yProvider: any = new LiveblocksProvider(room, yDoc)
yProvider = new LiveblocksProvider(room, yDoc)
setProvider(yProvider)
const binding = new MonacoBinding(
// 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}
</Tab>
))}
<Avatars />
</div>
<div
ref={editorContainerRef}

View File

@ -19,6 +19,7 @@ export function Cursors({ yProvider }: { yProvider: TypedLiveblocksProvider }) {
// On changes, update `awarenessUsers`
function setUsers() {
console.log("SET USERS")
setAwarenessUsers(
Array.from(yProvider.awareness.getStates()) as AwarenessList
)

View File

@ -10,6 +10,7 @@ import { Button } from "@/components/ui/button"
import { useState } from "react"
import EditSandboxModal from "./edit"
import ShareSandboxModal from "./share"
import { Avatars } from "../live/avatars"
export default function Navbar({
userData,
@ -58,6 +59,8 @@ export default function Navbar({
</div>
</div>
<div className="flex items-center space-x-4">
<Avatars />
<Button variant="outline" onClick={() => setIsShareOpen(true)}>
<Users className="w-4 h-4 mr-2" />
Share