mirror of
https://litchi.icu/ngc2207/judge.git
synced 2025-05-18 16:26:44 +00:00
feat(playground): add syntax highlighting to output display and update UI components for localization
This commit is contained in:
parent
dbfcc8dfce
commit
c0a8240008
@ -37,6 +37,7 @@
|
|||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
"react-resizable-panels": "^2.1.7",
|
"react-resizable-panels": "^2.1.7",
|
||||||
|
"react-syntax-highlighter": "^15.6.1",
|
||||||
"tailwind-merge": "^2.6.0",
|
"tailwind-merge": "^2.6.0",
|
||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7",
|
||||||
"vscode-languageclient": "~8.1.0",
|
"vscode-languageclient": "~8.1.0",
|
||||||
@ -50,6 +51,7 @@
|
|||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
"@types/react": "^19",
|
"@types/react": "^19",
|
||||||
"@types/react-dom": "^19",
|
"@types/react-dom": "^19",
|
||||||
|
"@types/react-syntax-highlighter": "^15.5.13",
|
||||||
"eslint": "^9",
|
"eslint": "^9",
|
||||||
"eslint-config-next": "15.1.3",
|
"eslint-config-next": "15.1.3",
|
||||||
"postcss": "^8",
|
"postcss": "^8",
|
||||||
|
@ -58,10 +58,15 @@ async function getOutputAndResultType(
|
|||||||
): Promise<RunCodeResult> {
|
): Promise<RunCodeResult> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let output = "";
|
let output = "";
|
||||||
|
|
||||||
stream.on("data", (chunk) => {
|
stream.on("data", (chunk) => {
|
||||||
|
console.debug("Chunk received:", Buffer.from(chunk).toString("hex"));
|
||||||
output += chunk.toString("utf8");
|
output += chunk.toString("utf8");
|
||||||
});
|
});
|
||||||
|
|
||||||
stream.on("end", () => {
|
stream.on("end", () => {
|
||||||
|
console.debug("Final output:", output);
|
||||||
|
|
||||||
const isSuccessful = !output.includes("error:");
|
const isSuccessful = !output.includes("error:");
|
||||||
const message = isSuccessful
|
const message = isSuccessful
|
||||||
? "运行成功:编译成功"
|
? "运行成功:编译成功"
|
||||||
@ -69,11 +74,12 @@ async function getOutputAndResultType(
|
|||||||
|
|
||||||
resolve({
|
resolve({
|
||||||
success: isSuccessful,
|
success: isSuccessful,
|
||||||
output,
|
output: output.replace(/[^\x20-\x7E\n\r]/g, ""), // 移除非打印字符
|
||||||
message,
|
message,
|
||||||
type: isSuccessful ? ResultType.Success : ResultType.CompilationError,
|
type: isSuccessful ? ResultType.Success : ResultType.CompilationError,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
stream.on("error", (err) => {
|
stream.on("error", (err) => {
|
||||||
reject(err);
|
reject(err);
|
||||||
});
|
});
|
||||||
|
@ -6,7 +6,7 @@ export default function Banner() {
|
|||||||
<p className="flex justify-center text-sm">
|
<p className="flex justify-center text-sm">
|
||||||
<a href="https://github.com/NGC2207/judge4c" className="group">
|
<a href="https://github.com/NGC2207/judge4c" className="group">
|
||||||
<span className="me-1 text-base leading-none">✨</span>
|
<span className="me-1 text-base leading-none">✨</span>
|
||||||
Introducing to Judge4c
|
了解更多关于 Judge4c 的信息
|
||||||
<ArrowRight
|
<ArrowRight
|
||||||
className="-mt-0.5 ms-2 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5"
|
className="-mt-0.5 ms-2 inline-flex opacity-60 transition-transform group-hover:translate-x-0.5"
|
||||||
size={16}
|
size={16}
|
||||||
|
@ -32,7 +32,7 @@ export default function Run() {
|
|||||||
strokeWidth={2}
|
strokeWidth={2}
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
Run
|
运行
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -21,7 +21,7 @@ export default function Chat() {
|
|||||||
return (
|
return (
|
||||||
<div className="h-full w-full flex flex-col border sm:rounded-lg shadow-md overflow-hidden transition-all duration-200 ease-out">
|
<div className="h-full w-full flex flex-col border sm:rounded-lg shadow-md overflow-hidden transition-all duration-200 ease-out">
|
||||||
<ExpandableChatHeader className="flex-col text-center justify-center border-[#3e4452] py-3">
|
<ExpandableChatHeader className="flex-col text-center justify-center border-[#3e4452] py-3">
|
||||||
<h1 className="text-xl font-semibold">Chat with AI Assistant ✨</h1>
|
<h1 className="text-xl font-semibold">与 AI 助教交谈 ✨</h1>
|
||||||
</ExpandableChatHeader>
|
</ExpandableChatHeader>
|
||||||
<ExpandableChatBody>
|
<ExpandableChatBody>
|
||||||
<ChatMessageList>
|
<ChatMessageList>
|
||||||
|
@ -20,7 +20,7 @@ export default function Nav() {
|
|||||||
</BreadcrumbItem>
|
</BreadcrumbItem>
|
||||||
<BreadcrumbSeparator />
|
<BreadcrumbSeparator />
|
||||||
<BreadcrumbItem>
|
<BreadcrumbItem>
|
||||||
<BreadcrumbPage>Playground</BreadcrumbPage>
|
<BreadcrumbPage>训练场</BreadcrumbPage>
|
||||||
</BreadcrumbItem>
|
</BreadcrumbItem>
|
||||||
</BreadcrumbList>
|
</BreadcrumbList>
|
||||||
</Breadcrumb>
|
</Breadcrumb>
|
||||||
|
@ -20,7 +20,7 @@ export default function Terminal() {
|
|||||||
strokeWidth={2}
|
strokeWidth={2}
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
Terminal
|
终端
|
||||||
</TabsTrigger>
|
</TabsTrigger>
|
||||||
<TabsTrigger
|
<TabsTrigger
|
||||||
value="comment"
|
value="comment"
|
||||||
@ -32,7 +32,7 @@ export default function Terminal() {
|
|||||||
strokeWidth={2}
|
strokeWidth={2}
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
Comment
|
评分
|
||||||
</TabsTrigger>
|
</TabsTrigger>
|
||||||
<TabsTrigger
|
<TabsTrigger
|
||||||
value="case"
|
value="case"
|
||||||
@ -44,7 +44,7 @@ export default function Terminal() {
|
|||||||
strokeWidth={2}
|
strokeWidth={2}
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
Testcase
|
测试用例
|
||||||
</TabsTrigger>
|
</TabsTrigger>
|
||||||
</TabsList>
|
</TabsList>
|
||||||
<div className="grow rounded-lg border border-border text-start bg-[#3e4452]">
|
<div className="grow rounded-lg border border-border text-start bg-[#3e4452]">
|
||||||
|
@ -41,7 +41,7 @@ export function Message({ type, message }: MessageProps) {
|
|||||||
const { icon: Icon, colorClass } = messageTypeIconMap[type];
|
const { icon: Icon, colorClass } = messageTypeIconMap[type];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="px-4 py-1">
|
<div className="px-4 py-1 bg-[#3e4452] pb-2">
|
||||||
<p className="grow text-sm">
|
<p className="grow text-sm">
|
||||||
<Icon
|
<Icon
|
||||||
className={`-mt-0.5 me-3 inline-flex ${colorClass}`}
|
className={`-mt-0.5 me-3 inline-flex ${colorClass}`}
|
||||||
|
@ -3,16 +3,21 @@
|
|||||||
import { Message } from "./components/message";
|
import { Message } from "./components/message";
|
||||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||||
import { useTerminalStore } from "@/store/useTerminalStore";
|
import { useTerminalStore } from "@/store/useTerminalStore";
|
||||||
|
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
|
||||||
|
import { oneDark } from "react-syntax-highlighter/dist/esm/styles/prism";
|
||||||
|
|
||||||
export default function ResultPage() {
|
export default function ResultPage() {
|
||||||
const { type, message, output } = useTerminalStore();
|
const { type, message, output } = useTerminalStore();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{type && message && (
|
{type && message && (
|
||||||
<ScrollArea className="h-full bg-[#3e4452]">
|
<ScrollArea className="h-full bg-[#272B33]">
|
||||||
<Message type={type} message={message} />
|
<Message type={type} message={message} />
|
||||||
{output && (
|
{output && (
|
||||||
<pre className="flex-grow px-4 text-sm text-white">{output}</pre>
|
<SyntaxHighlighter language="bash" style={oneDark}>
|
||||||
|
{output}
|
||||||
|
</SyntaxHighlighter>
|
||||||
)}
|
)}
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
)}
|
)}
|
||||||
|
Loading…
Reference in New Issue
Block a user