Skip to content

Commit fe8a06a

Browse files
WIP
1 parent 39659ff commit fe8a06a

10 files changed

+628
-31
lines changed

package-lock.json

Lines changed: 253 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"@babel/preset-react": "^7.24.1",
1717
"@babel/preset-typescript": "^7.24.1",
1818
"@mantine/core": "^7.9.1",
19+
"@types/jquery": "^3.5.30",
1920
"@types/node": "^20.12.11",
2021
"@types/react": "^18.3.2",
2122
"@types/react-dom": "^18.3.0",
@@ -67,11 +68,14 @@
6768
"axios": "^1.6.8",
6869
"classnames": "^2.5.1",
6970
"immer": "^10.1.1",
71+
"jquery": "^3.7.1",
72+
"jquery.terminal": "^2.41.2",
7073
"pyodide": "^0.25.1",
7174
"react": "^18.2.0",
7275
"react-ace": "^11.0.1",
7376
"react-dom": "^18.2.0",
7477
"react-error-boundary": "^4.0.13",
78+
"swr": "^2.2.5",
7579
"use-immer": "^0.9.0"
7680
}
7781
}

src/components/App.tsx

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@ import React, {useEffect, useState} from "react";
33

44
import {AppShell, Burger, createTheme, MantineColorsTuple, MantineProvider} from '@mantine/core';
55
import FetchWithProgress from "./FetchWithProgress";
6-
import AceEditor from "react-ace";
7-
import "ace-builds/src-noconflict/mode-jsx";
8-
import {usePyodide} from "../usePyodide";
6+
import {usePyodide} from "../hooks/usePyodide";
97
import {useDisclosure} from "@mantine/hooks";
108
import {useImmer} from "use-immer";
9+
import {PlaygroundTerminal} from "./PlaygroundTerminal";
1110

1211
const myColor: MantineColorsTuple = [
1312
'#e4f8ff',
@@ -40,13 +39,9 @@ const Inner: React.FC = () => {
4039
useEffect(() => {
4140
const go = async () => {
4241
if (data && !ran) {
43-
setRan(true);
44-
45-
pyodide.setStdout({
46-
batched: (msg) => setOutput(o => { o.push(msg); })
47-
})
4842

4943
console.warn("LOADING SQLITE");
44+
5045
await pyodide.loadPackage("sqlite3");
5146
console.warn("LOADED!");
5247

@@ -183,6 +178,7 @@ print(sys.meta_path)
183178
console.log(d.getVar("A"));
184179

185180
DataSmart.destroy();
181+
setRan(true);
186182

187183
} else {
188184
console.warn(`data = ${!!data}, p = ${!!pyodide}`);
@@ -192,8 +188,9 @@ print(sys.meta_path)
192188
go();
193189
}, [data, pyodide, ran, setRan]);
194190

195-
196191
return <>
192+
{/*{pyodide && data && ran && <TerminalComponent pyodide={pyodide}/>}*/}
193+
197194
<FetchWithProgress url={"assets/bitbake-2.8.0.zip"} data={data} setData={setData}/>
198195
<p>pyodide: {pyodideStatus}</p>
199196
<ul>
@@ -207,7 +204,6 @@ export const App: React.FC = () => {
207204

208205
return (
209206
<MantineProvider theme={theme}>
210-
211207
<AppShell
212208
header={{ height: 60 }}
213209
navbar={{
@@ -230,15 +226,8 @@ export const App: React.FC = () => {
230226
<AppShell.Navbar p="md">Navbar</AppShell.Navbar>
231227

232228
<AppShell.Main>
229+
<PlaygroundTerminal />
233230

234-
235-
<AceEditor
236-
mode="java"
237-
theme="github"
238-
name="UNIQUE_ID_OF_DIV"
239-
editorProps={{$blockScrolling: true}}
240-
/>
241-
<Inner/>
242231
</AppShell.Main>
243232
</AppShell>
244233

src/components/FetchWithProgress.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const FetchWithProgress: React.FC<FetchProgressProps> = (props: FetchProgressPro
1818
setLoading(true);
1919
const ret = await axios.get(props.url, {
2020
onDownloadProgress: progressEvent => {
21-
const percentage = Math.round(progressEvent.loaded * 100) / progressEvent.total;
21+
const percentage = Math.round((progressEvent.loaded * 100) / progressEvent.total);
2222
console.log(percentage);
2323
setProgress(percentage);
2424
},

src/components/JQueryTerminal.tsx

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import React, {useImperativeHandle, forwardRef, useRef, useEffect} from "react";
2+
import * as $ from "jquery";
3+
import 'jquery.terminal';
4+
import 'jquery.terminal/css/jquery.terminal.min.css';
5+
import {terminal} from "jquery";
6+
7+
interface Props {
8+
interpreter?: TypeOrArray<JQueryTerminal.Interpreter>,
9+
options?: JQueryTerminal.TerminalOptions
10+
}
11+
12+
const BANNER = `
13+
__ __ __ __ _____ __ __ _____ __ ___ ___ ___ _ __ __ __ __ ___ __ _ _ __ _ __
14+
| \\ \\ | _\\ / \\_ _/ \\ /' _/_ _/__\\| _ \\ __| | _,\\ | / \\\\ \`v' // _] _ \\/__\\| || | \\| | _\\
15+
| -< -< | v | /\\ || || /\\ |\`._\`. | || \\/ | v / _| | v_/ |_| /\\ |\`. .'| [/\\ v / \\/ | \\/ | | ' | v |
16+
|__/__/ |__/|_||_||_||_||_||___/ |_| \\__/|_|_\\___| |_| |___|_||_| !_! \\__/_|_\\\\__/ \\__/|_|\\__|__/
17+
18+
Copyright (C) Agilent Technologies 2024
19+
`;
20+
21+
export const JQueryTerminal: React.ForwardRefExoticComponent<React.PropsWithoutRef<Props> & React.RefAttributes<unknown>> = forwardRef(function JQueryTerminal(props, ref) {
22+
const terminalContainerRef = useRef(null);
23+
const terminalObjectRef = useRef<JQueryTerminal>(null);
24+
25+
useImperativeHandle(ref, () => {
26+
return {
27+
echo: async (arg: string, options: JQueryTerminal.animationOptions & JQueryTerminal.EchoOptions) => {
28+
if (terminalObjectRef.current) {
29+
return terminalObjectRef.current.echo(arg, options);
30+
}
31+
},
32+
update: (line: number, str: string) => {
33+
terminalObjectRef.current?.update(line, str);
34+
},
35+
freeze: () => {
36+
terminalObjectRef.current?.freeze(true);
37+
terminalObjectRef.current?.set_prompt("");
38+
},
39+
setInterpreter: (interpreter?: TypeOrArray<JQueryTerminal.Interpreter>) => {
40+
if (terminalObjectRef.current) {
41+
terminalObjectRef.current.set_interpreter(interpreter);
42+
}
43+
}
44+
};
45+
}, []);
46+
47+
useEffect(() => {
48+
const currentTerminal = terminalContainerRef.current;
49+
50+
if (currentTerminal) {
51+
terminalObjectRef.current = $(currentTerminal).terminal(props.interpreter, {
52+
greetings: BANNER,
53+
...props.options
54+
});
55+
}
56+
57+
return () => {
58+
if (currentTerminal) {
59+
$(currentTerminal).remove();
60+
}
61+
if (terminalObjectRef.current) {
62+
terminalObjectRef.current = null;
63+
}
64+
};
65+
}, []);
66+
67+
return <div ref={terminalContainerRef} id="terminal" style={{height: '300px'}}></div>;
68+
});

src/components/PlaygroundTerminal.tsx

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import {JQueryTerminal} from "./JQueryTerminal";
2+
import React, {useEffect, useRef} from "react";
3+
import {usePyodide} from "../hooks/usePyodide";
4+
5+
import {terminal} from "jquery";
6+
import {useEnvironmentSetup} from "../hooks/useEnvironmentSetup";
7+
8+
function progress(percent, width) {
9+
var size = Math.round(width*percent/100);
10+
var left = '', taken = '', i;
11+
for (i=size; i--;) {
12+
taken += '=';
13+
}
14+
if (taken.length > 0) {
15+
taken = taken.replace(/=$/, '>');
16+
}
17+
for (i=width-size; i--;) {
18+
left += ' ';
19+
}
20+
return '[' + taken + left + '] ' + percent + '%';
21+
}
22+
23+
export const PlaygroundTerminal: React.FC = () => {
24+
const terminalRef = useRef(null);
25+
26+
const {state} = useEnvironmentSetup();
27+
28+
useEffect(() => {
29+
terminalRef.current.echo("Setting up environment");
30+
terminalRef.current.freeze();
31+
}, [])
32+
33+
useEffect(() => {
34+
if (state.pyodideStatus === "idle") {
35+
terminalRef.current.echo(`Pyodide: ${state.pyodideStatus}`);
36+
terminalRef.current.echo(`Downloading bitbake: ${progress(state.bitbakeProgress, 80)}%`);
37+
}
38+
39+
terminalRef.current.update(-1, `Pyodide: ${state.pyodideStatus}`);
40+
terminalRef.current.update(-2, `Downloading bitbake: ${progress(state.bitbakeProgress, 80)}%`);
41+
}, [state]);
42+
//
43+
// useEffect(() => {
44+
// if (done && pyodide) {
45+
// terminalRef.current.echo("Unpacking BitBake...");
46+
// pyodide.unpackArchive(data, "zip", {
47+
// extractDir: "bb"
48+
// });
49+
// terminalRef.current.echo("Done!");
50+
// }
51+
// }, [data, done, pyodide]);
52+
53+
const interpreter = (command, term) => {
54+
55+
};
56+
57+
return (<JQueryTerminal interpreter={interpreter} ref={terminalRef}/>)
58+
}

0 commit comments

Comments
 (0)