| 
 | 1 | +import { useCallback, useMemo, useRef, useState } from "react";  | 
 | 2 | +import Header from "./Header";  | 
 | 3 | +import { persist, persistLocal, restore, stringify } from "./settings";  | 
 | 4 | +import { useTheme } from "./theme";  | 
 | 5 | +import { default as Editor, Source } from "./Editor";  | 
 | 6 | +import initRuff, { Workspace } from "../pkg/ruff_wasm";  | 
 | 7 | +import { loader } from "@monaco-editor/react";  | 
 | 8 | +import { setupMonaco } from "./setupMonaco";  | 
 | 9 | +import { DEFAULT_PYTHON_SOURCE } from "../constants";  | 
 | 10 | + | 
 | 11 | +export default function Chrome() {  | 
 | 12 | + const initPromise = useRef<null | Promise<void>>(null);  | 
 | 13 | + const [pythonSource, setPythonSource] = useState<null | string>(null);  | 
 | 14 | + const [settings, setSettings] = useState<null | string>(null);  | 
 | 15 | + const [revision, setRevision] = useState(0);  | 
 | 16 | + const [ruffVersion, setRuffVersion] = useState<string | null>(null);  | 
 | 17 | + | 
 | 18 | + const [theme, setTheme] = useTheme();  | 
 | 19 | + | 
 | 20 | + const handleShare = useCallback(() => {  | 
 | 21 | + if (settings == null || pythonSource == null) {  | 
 | 22 | + return;  | 
 | 23 | + }  | 
 | 24 | + | 
 | 25 | + persist(settings, pythonSource).catch((error) =>  | 
 | 26 | + console.error(`Failed to share playground: ${error}`),  | 
 | 27 | + );  | 
 | 28 | + }, [pythonSource, settings]);  | 
 | 29 | + | 
 | 30 | + if (initPromise.current == null) {  | 
 | 31 | + initPromise.current = startPlayground()  | 
 | 32 | + .then(({ sourceCode, settings, ruffVersion }) => {  | 
 | 33 | + setPythonSource(sourceCode);  | 
 | 34 | + setSettings(settings);  | 
 | 35 | + setRuffVersion(ruffVersion);  | 
 | 36 | + setRevision(1);  | 
 | 37 | + })  | 
 | 38 | + .catch((error) => {  | 
 | 39 | + console.error("Failed to initialize playground.", error);  | 
 | 40 | + });  | 
 | 41 | + }  | 
 | 42 | + | 
 | 43 | + const handleSourceChanged = useCallback(  | 
 | 44 | + (source: string) => {  | 
 | 45 | + setPythonSource(source);  | 
 | 46 | + setRevision((revision) => revision + 1);  | 
 | 47 | + | 
 | 48 | + if (settings != null) {  | 
 | 49 | + persistLocal({ pythonSource: source, settingsSource: settings });  | 
 | 50 | + }  | 
 | 51 | + },  | 
 | 52 | + [settings],  | 
 | 53 | + );  | 
 | 54 | + | 
 | 55 | + const handleSettingsChanged = useCallback(  | 
 | 56 | + (settings: string) => {  | 
 | 57 | + setSettings(settings);  | 
 | 58 | + setRevision((revision) => revision + 1);  | 
 | 59 | + | 
 | 60 | + if (pythonSource != null) {  | 
 | 61 | + persistLocal({ pythonSource: pythonSource, settingsSource: settings });  | 
 | 62 | + }  | 
 | 63 | + },  | 
 | 64 | + [pythonSource],  | 
 | 65 | + );  | 
 | 66 | + | 
 | 67 | + const source: Source | null = useMemo(() => {  | 
 | 68 | + if (pythonSource == null || settings == null) {  | 
 | 69 | + return null;  | 
 | 70 | + }  | 
 | 71 | + | 
 | 72 | + return { pythonSource, settingsSource: settings };  | 
 | 73 | + }, [settings, pythonSource]);  | 
 | 74 | + | 
 | 75 | + return (  | 
 | 76 | + <main className="flex flex-col h-full bg-ayu-background dark:bg-ayu-background-dark">  | 
 | 77 | + <Header  | 
 | 78 | + edit={revision}  | 
 | 79 | + theme={theme}  | 
 | 80 | + version={ruffVersion}  | 
 | 81 | + onChangeTheme={setTheme}  | 
 | 82 | + onShare={handleShare}  | 
 | 83 | + />  | 
 | 84 | + | 
 | 85 | + <div className="flex flex-grow">  | 
 | 86 | + {source != null && (  | 
 | 87 | + <Editor  | 
 | 88 | + theme={theme}  | 
 | 89 | + source={source}  | 
 | 90 | + onSettingsChanged={handleSettingsChanged}  | 
 | 91 | + onSourceChanged={handleSourceChanged}  | 
 | 92 | + />  | 
 | 93 | + )}  | 
 | 94 | + </div>  | 
 | 95 | + </main>  | 
 | 96 | + );  | 
 | 97 | +}  | 
 | 98 | + | 
 | 99 | +// Run once during startup. Initializes monaco, loads the wasm file, and restores the previous editor state.  | 
 | 100 | +async function startPlayground(): Promise<{  | 
 | 101 | + sourceCode: string;  | 
 | 102 | + settings: string;  | 
 | 103 | + ruffVersion: string;  | 
 | 104 | +}> {  | 
 | 105 | + await initRuff();  | 
 | 106 | + const monaco = await loader.init();  | 
 | 107 | + | 
 | 108 | + console.log(monaco);  | 
 | 109 | + | 
 | 110 | + setupMonaco(monaco);  | 
 | 111 | + | 
 | 112 | + const response = await restore();  | 
 | 113 | + const [settingsSource, pythonSource] = response ?? [  | 
 | 114 | + stringify(Workspace.defaultSettings()),  | 
 | 115 | + DEFAULT_PYTHON_SOURCE,  | 
 | 116 | + ];  | 
 | 117 | + | 
 | 118 | + return {  | 
 | 119 | + sourceCode: pythonSource,  | 
 | 120 | + settings: settingsSource,  | 
 | 121 | + ruffVersion: Workspace.version(),  | 
 | 122 | + };  | 
 | 123 | +}  | 
0 commit comments