Skip to content

Commit 9631281

Browse files
committed
fix(code-editor-panel): dynamic loading monaco editor on client
1 parent 7e12012 commit 9631281

File tree

2 files changed

+17
-13
lines changed

2 files changed

+17
-13
lines changed

frontend/src/app/practice/[id]/page.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,21 @@
22

33
import { useEffect } from "react";
44
import { useRouter, useParams } from "next/navigation";
5+
import dynamic from "next/dynamic";
56
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "@/components/ui/resizable";
67
import Header from "@/components/ui/header";
78
import QuestionPanel from "@/components/practice/question-panel";
8-
import CodeEditorPanel from "@/components/practice/code-editor-panel";
99
import CommunicationPanel from "@/components/practice/communication-panel";
1010
import CodeOutputPanel from "@/components/practice/code-output-panel";
1111
import { Button } from "@/components/ui/button";
1212
import { Spinner } from "@/components/ui/spinner";
1313
import { useCollaborationState, useCollaborationActions } from "@/stores/collaboration-store";
1414

15+
const CodeEditorPanel = dynamic(() => import("@/components/practice/code-editor-panel"), {
16+
ssr: false,
17+
loading: () => <div className="h-full flex items-center justify-center">Loading editor...</div>,
18+
});
19+
1520
export default function PracticePage() {
1621
const router = useRouter();
1722
const params = useParams();
@@ -72,11 +77,6 @@ export default function PracticePage() {
7277
<div className="h-screen w-full flex flex-col">
7378
<Header>
7479
<div className="flex items-center gap-4">
75-
{/* {isReadOnly && (
76-
<span className="text-sm text-muted-foreground px-3 py-1 bg-muted rounded">
77-
Read-Only Mode
78-
</span>
79-
)} */}
8080
<Button variant={"destructive"} onClick={handleLeaveSession}>
8181
Leave Room
8282
</Button>

frontend/src/components/practice/code-editor-panel.tsx

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
import { useRef, useEffect, useState } from "react";
44
import { useParams } from "next/navigation";
55
import { Editor } from "@monaco-editor/react";
6-
import { editor } from "monaco-editor";
6+
import type { editor } from "monaco-editor";
7+
import * as monaco from "monaco-editor";
78
import * as Y from "yjs";
89
import { WebsocketProvider } from "y-websocket";
910
import { MonacoBinding } from "y-monaco";
@@ -48,6 +49,7 @@ export default function CodeEditorPanel({ readOnly = false }: CodeEditorPanelPro
4849
const { changeLanguage, updateLanguage } = useCollaborationActions();
4950

5051
const [editorInstance, setEditorInstance] = useState<editor.IStandaloneCodeEditor | null>(null);
52+
const [monacoInstance, setMonacoInstance] = useState<typeof monaco | null>(null);
5153
const [connectionStatus, setConnectionStatus] = useState<ConnectionState>(
5254
ConnectionState.DISCONNECTED,
5355
);
@@ -101,12 +103,10 @@ export default function CodeEditorPanel({ readOnly = false }: CodeEditorPanelPro
101103
try {
102104
const message = JSON.parse(event.data);
103105
if (message.type === "language-change-notification") {
104-
console.log("Language changed to:", message.data.language);
105106
const programmingLanguage = message.data.language as ProgrammingLanguage;
106107
updateLanguage(programmingLanguage);
107108
toast.info(`Language changed to ${programmingLanguageDisplayMap[programmingLanguage]}`);
108109
} else if (message.type === "room-close-notification") {
109-
console.log("Room closed at:", message.data.closedAt);
110110
toast.warn("The collaboration room has been closed");
111111
}
112112
} catch {
@@ -126,13 +126,13 @@ export default function CodeEditorPanel({ readOnly = false }: CodeEditorPanelPro
126126

127127
// Update Monaco language when room language changes
128128
useEffect(() => {
129-
if (editorInstance && monacoLanguage) {
129+
if (editorInstance && monacoLanguage && monacoInstance) {
130130
const model = editorInstance.getModel();
131131
if (model) {
132-
editor.setModelLanguage(model, monacoLanguage);
132+
monacoInstance.editor.setModelLanguage(model, monacoLanguage);
133133
}
134134
}
135-
}, [editorInstance, monacoLanguage]);
135+
}, [editorInstance, monacoLanguage, monacoInstance]);
136136

137137
// Handle language change from dropdown
138138
const handleLanguageChange = async (language: ProgrammingLanguage) => {
@@ -143,8 +143,12 @@ export default function CodeEditorPanel({ readOnly = false }: CodeEditorPanelPro
143143
};
144144

145145
// Handle editor mount
146-
const handleEditorDidMount = (editorRef: editor.IStandaloneCodeEditor) => {
146+
const handleEditorDidMount = (
147+
editorRef: editor.IStandaloneCodeEditor,
148+
monacoRef: typeof monaco,
149+
) => {
147150
setEditorInstance(editorRef);
151+
setMonacoInstance(monacoRef);
148152

149153
// Set document content for read-only mode
150154
if (readOnly && documentContent) {

0 commit comments

Comments
 (0)