Improved editor

This commit is contained in:
2026-02-06 23:50:32 +01:00
parent 3b2809ed85
commit 3c7e964d1c
2 changed files with 43 additions and 43 deletions
+7 -43
View File
@@ -9,6 +9,8 @@ import { json } from "@codemirror/lang-json";
import { python } from "@codemirror/lang-python";
import { java } from "@codemirror/lang-java";
import { useEffect, useState } from "react";
import useAction from "@/hook/use-action";
import { getLiveRunMoves } from "@/modules/live-run/actions";
type Language =
| "javascript"
@@ -48,51 +50,12 @@ type Move = {
};
};
const code = `// Import the necessary React library features
import { createRoot } from 'react-dom/client';
// Define a functional component named "App"
// Component names must start with a capital letter
function App() {
// Components return JSX markup
return (
<h1>Hello, world!</h1>
);
}
// Target a DOM element in your HTML (e.g., <div id="root"></div>)
const domNode = document.getElementById('root');
// Create a root and render your component into the DOM
const root = createRoot(domNode);
root.render(<App />);`.repeat(3);
// Helper to split text into chunks of ~4 chars
function chunkText(text: string, size = 4) {
const chunks = [];
for (let i = 0; i < text.length; i += size) {
chunks.push(text.slice(i, i + size));
}
return chunks;
}
const chunks = chunkText(code, 4);
const moves: Move[] = chunks.map((chunk, index) => ({
latency: 1, // 100ms per chunk
cursor: index * 4, // approximate cursor position
changes: {
from: index * 4,
to: index * 4,
insert: chunk,
},
}));
export default function Editor() {
const [editorView, setEditorView] = useState<EditorView>();
const [moves] = useAction<Move[]>(getLiveRunMoves);
useEffect(() => {
if (!editorView) return;
if (!editorView || !moves) return;
let cancelled = false;
@@ -115,6 +78,7 @@ export default function Editor() {
};
(async () => {
if (!moves) return;
for (const move of moves) {
if (cancelled) break;
await executeMove(move);
@@ -122,9 +86,9 @@ export default function Editor() {
})();
return () => {
cancelled = true; // stop future moves
cancelled = true;
};
}, [editorView]);
}, [editorView, moves]);
return (
<CodeMirror
+36
View File
@@ -50,3 +50,39 @@ export async function getLiveRuns(): Promise<Run[]> {
},
];
}
export async function getLiveRunMoves() {
const code = `// Import the necessary React library features
import { createRoot } from 'react-dom/client';
// Define a functional component named "App"
// Component names must start with a capital letter
function App() {
// Components return JSX markup
return (
<h1>Hello, world!</h1>
);
}
// Target a DOM element in your HTML (e.g., <div id="root"></div>)
const domNode = document.getElementById('root');
// Create a root and render your component into the DOM
const root = createRoot(domNode);
root.render(<App />);`.repeat(3);
const chunks = [];
for (let i = 0; i < code.length; i += 4) {
chunks.push(code.slice(i, i + 4));
}
return chunks.map((chunk, index) => ({
latency: 1, // 100ms per chunk
cursor: index * 4, // approximate cursor position
changes: {
from: index * 4,
to: index * 4,
insert: chunk,
},
}));
}