import React, { useEffect, useRef } from "react"; import { useSnapshot, ref } from "valtio"; import Editor, { loader } from "@monaco-editor/react"; import type monaco from "monaco-editor"; import { ArrowBendLeftUp } from "phosphor-react"; import { useTheme } from "next-themes"; import { useRouter } from "next/router"; import Box from "./Box"; import Container from "./Container"; import dark from "../theme/editor/amy.json"; import light from "../theme/editor/xcode_default.json"; import { saveFile } from "../state/actions"; import state from "../state"; import EditorNavigation from "./EditorNavigation"; import Text from "./Text"; import { MonacoServices } from "@codingame/monaco-languageclient"; import { createLanguageClient, createWebSocket } from "../utils/languageClient"; import { listen } from "@codingame/monaco-jsonrpc"; import ReconnectingWebSocket from "reconnecting-websocket"; loader.config({ paths: { vs: "https://cdn.jsdelivr.net/npm/monaco-editor@0.30.1/min/vs", }, }); const HooksEditor = () => { const editorRef = useRef(); const subscriptionRef = useRef(null); const snap = useSnapshot(state); const router = useRouter(); const { theme } = useTheme(); useEffect(() => { return () => { subscriptionRef?.current?.close(); }; }, []); return ( {snap.files.length > 0 && router.isReady ? ( { if (!snap.editorCtx) { snap.files.forEach((file) => monaco.editor.createModel( file.content, file.language, monaco.Uri.parse(`file://work/c/${file.name}`) ) ); } // create the web socket if (!subscriptionRef.current) { monaco.languages.register({ id: "c", extensions: [".c", ".h"], aliases: ["C", "c", "H", "h"], mimetypes: ["text/plain"], }); MonacoServices.install(monaco); const webSocket = createWebSocket( process.env.NEXT_PUBLIC_LANGUAGE_SERVER_API_ENDPOINT || "" ); subscriptionRef.current = webSocket; // listen when the web socket is opened listen({ webSocket: webSocket as WebSocket, onConnection: (connection) => { // create and start the language client const languageClient = createLanguageClient(connection); const disposable = languageClient.start(); connection.onClose(() => { try { // disposable.stop(); disposable.dispose(); } catch (err) { console.log("err", err); } }); }, }); } // // hook editor to global state // editor.updateOptions({ // minimap: { // enabled: false, // }, // ...snap.editorSettings, // }); if (!state.editorCtx) { state.editorCtx = ref(monaco.editor); // @ts-expect-error monaco.editor.defineTheme("dark", dark); // @ts-expect-error monaco.editor.defineTheme("light", light); } }} onMount={(editor, monaco) => { editorRef.current = editor; editor.updateOptions({ glyphMargin: true, lightbulb: { enabled: true, }, }); editor.addCommand( monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, () => { saveFile(); } ); }} theme={theme === "dark" ? "dark" : "light"} /> ) : ( {!snap.loading && router.isReady && ( Click the link above to create a your file )} )} ); }; export default HooksEditor;