Compare commits

..

12 Commits

7 changed files with 45 additions and 47 deletions

View File

@ -143,8 +143,6 @@ io.on("connection", async (socket) => {
isOwner: boolean; isOwner: boolean;
}; };
console.log("user:",data)
if (data.isOwner) { if (data.isOwner) {
isOwnerConnected = true; isOwnerConnected = true;
connections[data.sandboxId] = (connections[data.sandboxId] ?? 0) + 1; connections[data.sandboxId] = (connections[data.sandboxId] ?? 0) + 1;
@ -185,7 +183,6 @@ io.on("connection", async (socket) => {
fixPermissions(); fixPermissions();
socket.emit("loaded", sandboxFiles.files); socket.emit("loaded", sandboxFiles.files);
console.log("files got", sandboxFiles.files)
socket.on("getFile", (fileId: string, callback) => { socket.on("getFile", (fileId: string, callback) => {
console.log(fileId); console.log(fileId);

View File

@ -6,6 +6,7 @@ import { notFound, redirect } from "next/navigation"
import Loading from "@/components/editor/loading" import Loading from "@/components/editor/loading"
import dynamic from "next/dynamic" import dynamic from "next/dynamic"
import fs from "fs" import fs from "fs"
import { TerminalProvider } from "@/context/TerminalContext"
export const revalidate = 0 export const revalidate = 0
@ -87,8 +88,10 @@ export default async function CodePage({ params }: { params: { id: string } }) {
} }
return ( return (
<>
<div className="overflow-hidden overscroll-none w-screen flex flex-col h-screen bg-background"> <div className="overflow-hidden overscroll-none w-screen flex flex-col h-screen bg-background">
<Room id={sandboxId}> <Room id={sandboxId}>
<TerminalProvider>
<Navbar userData={userData} sandboxData={sandboxData} shared={shared} /> <Navbar userData={userData} sandboxData={sandboxData} shared={shared} />
<div className="w-screen flex grow"> <div className="w-screen flex grow">
<CodeEditor <CodeEditor
@ -96,7 +99,9 @@ export default async function CodePage({ params }: { params: { id: string } }) {
sandboxData={sandboxData} sandboxData={sandboxData}
/> />
</div> </div>
</TerminalProvider>
</Room> </Room>
</div> </div>
</>
) )
} }

View File

@ -6,7 +6,6 @@ import { ThemeProvider } from "@/components/layout/themeProvider"
import { ClerkProvider } from "@clerk/nextjs" import { ClerkProvider } from "@clerk/nextjs"
import { Toaster } from "@/components/ui/sonner" import { Toaster } from "@/components/ui/sonner"
import { Analytics } from "@vercel/analytics/react" import { Analytics } from "@vercel/analytics/react"
import { TerminalProvider } from '@/context/TerminalContext';
import { PreviewProvider } from "@/context/PreviewContext"; import { PreviewProvider } from "@/context/PreviewContext";
import { SocketProvider } from '@/context/SocketContext' import { SocketProvider } from '@/context/SocketContext'
@ -32,9 +31,7 @@ export default function RootLayout({
> >
<SocketProvider> <SocketProvider>
<PreviewProvider> <PreviewProvider>
<TerminalProvider>
{children} {children}
</TerminalProvider>
</PreviewProvider> </PreviewProvider>
</SocketProvider> </SocketProvider>
<Analytics /> <Analytics />

View File

@ -49,11 +49,9 @@ export default function Dashboard({
const q = searchParams.get("q") const q = searchParams.get("q")
const router = useRouter() const router = useRouter()
useEffect(() => { useEffect(() => { // update the dashboard to show a new project
// if (!sandboxes) { router.refresh()
router.refresh() // fix: update the dashboard to show the new project }, [])
// }
}, [sandboxes])
return ( return (
<> <>

View File

@ -1,37 +1,48 @@
"use client" "use client"
import { SetStateAction, useCallback, useEffect, useRef, useState } from "react" import { SetStateAction, useCallback, useEffect, useRef, useState } from "react"
import monaco from "monaco-editor"
import Editor, { BeforeMount, OnMount } from "@monaco-editor/react" import { Sandbox, User, TFile, TFolder, TTab } from "@/lib/types"
import { toast } from "sonner"
// Authentication
import { useClerk } from "@clerk/nextjs" import { useClerk } from "@clerk/nextjs"
// Liveblocks
import * as Y from "yjs" import * as Y from "yjs"
import LiveblocksProvider from "@liveblocks/yjs" import LiveblocksProvider from "@liveblocks/yjs"
import { MonacoBinding } from "y-monaco" import { MonacoBinding } from "y-monaco"
import { Awareness } from "y-protocols/awareness" import { Awareness } from "y-protocols/awareness"
import { TypedLiveblocksProvider, useRoom, useSelf } from "@/liveblocks.config" import { TypedLiveblocksProvider, useRoom, useSelf } from "@/liveblocks.config"
// Icons
import { FileJson, Loader2, TerminalSquare } from "lucide-react"
// Contexts
import { PreviewProvider, usePreview } from '@/context/PreviewContext';
import { useSocket } from "@/context/SocketContext"
// External Components
import monaco from "monaco-editor"
import { Terminal } from "@xterm/xterm"
import Editor, { BeforeMount, OnMount } from "@monaco-editor/react"
import { toast } from "sonner"
import { import {
ResizableHandle, ResizableHandle,
ResizablePanel, ResizablePanel,
ResizablePanelGroup, ResizablePanelGroup,
} from "@/components/ui/resizable" } from "@/components/ui/resizable"
import { FileJson, Loader2, TerminalSquare } from "lucide-react" import { ImperativePanelHandle } from "react-resizable-panels"
// Editor Components
import Tab from "../ui/tab" import Tab from "../ui/tab"
import Sidebar from "./sidebar" import Sidebar from "./sidebar"
import GenerateInput from "./generate" import GenerateInput from "./generate"
import { Sandbox, User, TFile, TFolder, TTab } from "@/lib/types"
import { addNew, processFileType, validateName, debounce } from "@/lib/utils" import { addNew, processFileType, validateName, debounce } from "@/lib/utils"
import { Cursors } from "./live/cursors" import { Cursors } from "./live/cursors"
import { Terminal } from "@xterm/xterm"
import DisableAccessModal from "./live/disableModal" import DisableAccessModal from "./live/disableModal"
import Loading from "./loading" import Loading from "./loading"
import PreviewWindow from "./preview" import PreviewWindow from "./preview"
import Terminals from "./terminals" import Terminals from "./terminals"
import { ImperativePanelHandle } from "react-resizable-panels"
import { PreviewProvider, usePreview } from '@/context/PreviewContext';
import { useSocket } from "@/context/SocketContext"
export default function CodeEditor({ export default function CodeEditor({
userData, userData,
@ -41,24 +52,17 @@ export default function CodeEditor({
sandboxData: Sandbox sandboxData: Sandbox
}) { }) {
//SocketContext functions and effects // Socket to the backend server
const { socket, setUserAndSandboxId } = useSocket(); const { socket, setUserAndSandboxId } = useSocket();
useEffect(() => { useEffect(() => {
console.log('Effect triggered:', { socket, userData, sandboxData }); // Pass the user and sandbox ID to the socket, causing the socket to be created and to connect.
// Ensure userData.id and sandboxData.id are available before attempting to connect setUserAndSandboxId(userData.id, sandboxData.id);
if (userData.id && sandboxData.id) { }, []);
// Check if the socket is not initialized or not connected
if (!socket || (socket && !socket.connected)) {
// Initialize socket connection
console.log('Initializing socket...');
setUserAndSandboxId(userData.id, sandboxData.id);
}
}
}, [socket, userData.id, sandboxData.id, setUserAndSandboxId]);
//Preview Button state // Preview panel state
const [isPreviewCollapsed, setIsPreviewCollapsed] = useState(true) const [isPreviewCollapsed, setIsPreviewCollapsed] = useState(true)
// When the owner closes the project, isDisabled gets set for the other users.
const [disableAccess, setDisableAccess] = useState({ const [disableAccess, setDisableAccess] = useState({
isDisabled: false, isDisabled: false,
message: "", message: "",
@ -433,7 +437,7 @@ export default function CodeEditor({
return () => { return () => {
socket?.disconnect() socket?.disconnect()
} }
}, []) }, [socket])
// Socket event listener effect // Socket event listener effect
useEffect(() => { useEffect(() => {
@ -445,7 +449,6 @@ export default function CodeEditor({
const onLoadedEvent = (files: (TFolder | TFile)[]) => { const onLoadedEvent = (files: (TFolder | TFile)[]) => {
setFiles(files) setFiles(files)
console.log("loaded", files)
} }
const onError = (message: string) => { const onError = (message: string) => {
@ -484,7 +487,6 @@ export default function CodeEditor({
socket?.off("disableAccess", onDisableAccess) socket?.off("disableAccess", onDisableAccess)
socket?.off("previewURL", loadPreviewURL) socket?.off("previewURL", loadPreviewURL)
} }
// }, []);
}, [socket, terminals, setTerminals, setFiles, toast, setDisableAccess, isOwner, loadPreviewURL]); }, [socket, terminals, setTerminals, setFiles, toast, setDisableAccess, isOwner, loadPreviewURL]);
// Helper functions for tabs: // Helper functions for tabs:
@ -495,14 +497,13 @@ export default function CodeEditor({
const fileCache = useRef(new Map()); const fileCache = useRef(new Map());
// Debounced function to get file content // Debounced function to get file content
const debouncedGetFile = useCallback( const debouncedGetFile =
debounce((tabId, callback) => { (tabId: any, callback: any) => {
socket?.emit('getFile', tabId, callback); socket?.emit('getFile', tabId, callback);
}, 300), // 300ms debounce delay, adjust as needed } // 300ms debounce delay, adjust as needed
[]
); const selectFile = (tab: TTab) => {
const selectFile = useCallback((tab: TTab) => {
if (tab.id === activeFileId) return; if (tab.id === activeFileId) return;
setGenerate((prev) => ({ ...prev, show: false })); setGenerate((prev) => ({ ...prev, show: false }));
@ -527,7 +528,7 @@ export default function CodeEditor({
setEditorLanguage(processFileType(tab.name)); setEditorLanguage(processFileType(tab.name));
setActiveFileId(tab.id); setActiveFileId(tab.id);
}, [activeFileId, tabs, debouncedGetFile]); };
// Close tab and remove from tabs // Close tab and remove from tabs
const closeTab = (id: string) => { const closeTab = (id: string) => {

View File

@ -27,7 +27,7 @@ export default function Navbar({
const [isShareOpen, setIsShareOpen] = useState(false); const [isShareOpen, setIsShareOpen] = useState(false);
const [isRunning, setIsRunning] = useState(false); const [isRunning, setIsRunning] = useState(false);
const isOwner = sandboxData.userId === userData.id;; const isOwner = sandboxData.userId === userData.id;
return ( return (
<> <>