"use client"; import { Send } from "lucide-react"; import * as monaco from "monaco-editor"; import { Button } from "@/components/ui/button"; import { runCode } from "@/actions/docker/compile"; import { useEffect, useRef, useState } from "react"; import { Editor, loader } from "@monaco-editor/react"; import { MonacoLanguageClient } from "monaco-languageclient"; import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area"; import { COriginal, CplusplusOriginal, JavaOriginal } from "devicons-react"; import { connectToLanguageServer, LSP_SUPPORTED_LANGUAGES } from "@/lib/lsp"; import { codeToHtml } from "shiki"; const files: { [key: string]: { name: string; language: string; value: string }; } = { c: { name: "main.c", language: "c", value: `#include int main() { printf("Hello, World!"); return 0; }`, }, cpp: { name: "main.cpp", language: "cpp", value: `#include int main() { std::cout << "Hello, World!"; return 0; }`, }, java: { name: "Main.java", language: "java", value: `public class Main { public static void main(String[] args) { System.out.println("Hello, World!"); } }`, }, }; loader.config({ monaco }); export default function PlaygroundPage() { const [language, setLanguage] = useState("c"); const [highlightedMessage, setHighlightedMessage] = useState(""); const file = files[language]; const editorRef = useRef(null); const webSocketRef = useRef(null); const languageClientRef = useRef(null); useEffect(() => { const handleLanguageChange = async () => { if (editorRef.current) { const model = editorRef.current.getModel(); if (model) { const lineCount = model.getLineCount(); const lastLineLength = model.getLineLength(lineCount); editorRef.current.setPosition({ lineNumber: lineCount, column: lastLineLength + 1, }); editorRef.current.focus(); if ( languageClientRef.current && language in LSP_SUPPORTED_LANGUAGES ) { await languageClientRef.current.stop(); languageClientRef.current = null; } if ( webSocketRef.current && webSocketRef.current.readyState !== WebSocket.CLOSED && webSocketRef.current.readyState !== WebSocket.CLOSING && language in LSP_SUPPORTED_LANGUAGES ) { webSocketRef.current.close(); webSocketRef.current = null; } if (language in LSP_SUPPORTED_LANGUAGES) { try { const languageClient = await connectToLanguageServer( language, webSocketRef ); languageClientRef.current = languageClient; } catch (error) { console.error("Failed to connect to language server:", error); } } } } }; handleLanguageChange(); }, [language]); const handleSubmit = async () => { const code = editorRef.current?.getValue(); if (!code) { console.error("No code to compile"); return; } const result = await runCode(code, language); // 根据编译结果显示不同的信息 const statusMessage = result.success ? "Compilation successful" : "Compilation failed"; const fullMessage = `${statusMessage}\n\n${result.output}`; const highlighted = await codeToHtml(fullMessage, { lang: "log", // 或者根据你的需求选择合适的语言 theme: "one-dark-pro", }); setHighlightedMessage(highlighted); }; return (
setLanguage("c")} disabled={language === "c"} > setLanguage("cpp")} disabled={language === "cpp"} > setLanguage("java")} disabled={language === "java"} >
{ editorRef.current = editor; if (editorRef.current) { const model = editorRef.current.getModel(); if (model) { const lineCount = model.getLineCount(); const lastLineLength = model.getLineLength(lineCount); editorRef.current.setPosition({ lineNumber: lineCount, column: lastLineLength + 1, }); editorRef.current.focus(); connectToLanguageServer(language, webSocketRef) .then((languageClient) => { languageClientRef.current = languageClient; }) .catch((error) => { console.error( "Failed to connect to language server:", error ); }); } } }} />
); }