show compile errors in ui
This commit is contained in:
parent
a623308496
commit
664dbf4f6b
|
@ -1,6 +1,8 @@
|
|||
import { useEffect, useState } from "react";
|
||||
import { useMonaco, type Monaco } from "@monaco-editor/react";
|
||||
import { useImmer, type Updater } from "use-immer";
|
||||
import ThemeProvider from "@mui/material/styles/ThemeProvider";
|
||||
import ErrorDisplay from "./playground/ErrorDisplay";
|
||||
import FileView from "./playground/FileView";
|
||||
import Editor from "./playground/Editor";
|
||||
import Header from "./playground/Header";
|
||||
|
@ -16,7 +18,6 @@ import "@styles/playground.scss";
|
|||
|
||||
import mainFileContent from "@assets/playground/main.shu?raw";
|
||||
import packTomlContent from "@assets/playground/pack.toml?raw";
|
||||
import ThemeProvider from "@mui/material/styles/ThemeProvider";
|
||||
|
||||
const FILE_STORAGE_KEY = "playground-files";
|
||||
const DEFAULT_FILES = {
|
||||
|
@ -40,6 +41,18 @@ const DEFAULT_FILES = {
|
|||
};
|
||||
|
||||
export default function Playground({ lang }: { lang: PlaygroundLang }) {
|
||||
const [errorMsg, setErrorMsg] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
(window as any).playground = {
|
||||
showError: (message: string) => {
|
||||
if (message.length > 0) {
|
||||
setErrorMsg(message);
|
||||
}
|
||||
},
|
||||
};
|
||||
}, []);
|
||||
|
||||
initWasm().catch((err) => {
|
||||
console.error(err);
|
||||
});
|
||||
|
@ -63,8 +76,6 @@ export default function Playground({ lang }: { lang: PlaygroundLang }) {
|
|||
},
|
||||
} as Directory;
|
||||
loadFiles(monaco, updateRootDir, withRoot);
|
||||
} else {
|
||||
alert("Compilation failed");
|
||||
}
|
||||
} else {
|
||||
console.error("monaco has not loaded");
|
||||
|
@ -79,8 +90,6 @@ export default function Playground({ lang }: { lang: PlaygroundLang }) {
|
|||
a.href = data;
|
||||
a.download = "shulkerscript-pack.zip";
|
||||
a.click();
|
||||
} else {
|
||||
alert("Compilation failed");
|
||||
}
|
||||
} else {
|
||||
console.error("monaco has not loaded");
|
||||
|
@ -167,6 +176,7 @@ export default function Playground({ lang }: { lang: PlaygroundLang }) {
|
|||
marginTop: "0.5cm",
|
||||
}}
|
||||
>
|
||||
<ErrorDisplay error={errorMsg} setError={setErrorMsg} />
|
||||
<Header
|
||||
lang={lang.header}
|
||||
onSave={onSave}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
import Button from "@mui/material/Button";
|
||||
import Dialog from "@mui/material/Dialog";
|
||||
import DialogActions from "@mui/material/DialogActions";
|
||||
import DialogContent from "@mui/material/DialogContent";
|
||||
import DialogTitle from "@mui/material/DialogTitle";
|
||||
|
||||
export default function ErrorDisplay({
|
||||
error,
|
||||
setError,
|
||||
}: {
|
||||
error: string | null;
|
||||
setError: (error: string | null) => void;
|
||||
}) {
|
||||
return (
|
||||
<Dialog open={error !== null} onClose={() => setError(null)}>
|
||||
<DialogTitle>Error during compilation!</DialogTitle>
|
||||
<DialogContent>
|
||||
<div
|
||||
style={{
|
||||
backgroundColor: "black",
|
||||
padding: "15px",
|
||||
borderRadius: "15px",
|
||||
fontSize: "1.2em",
|
||||
}}
|
||||
>
|
||||
<code
|
||||
style={{
|
||||
whiteSpace: "break-spaces",
|
||||
fontFamily: "monospace",
|
||||
}}
|
||||
dangerouslySetInnerHTML={{ __html: error ?? "" }}
|
||||
></code>
|
||||
</div>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={() => setError(null)}>Close</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
|
@ -17,3 +17,5 @@ anyhow = "1.0.86"
|
|||
zip = { version = "2.1.3", default-features = false, features = ["deflate"] }
|
||||
base64 = "0.22.1"
|
||||
console_error_panic_hook = "0.1.7"
|
||||
ansi-to-html = "0.2.1"
|
||||
colored = "2.1.0"
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use std::{
|
||||
cell::Cell,
|
||||
fmt::Display,
|
||||
io::{Cursor, Write},
|
||||
path::PathBuf,
|
||||
sync::Mutex,
|
||||
};
|
||||
|
||||
use anyhow::Result;
|
||||
|
@ -24,6 +24,9 @@ extern "C" {
|
|||
fn log(s: &str);
|
||||
#[wasm_bindgen(js_namespace = console, js_name = error)]
|
||||
fn log_err(s: &str);
|
||||
|
||||
#[wasm_bindgen(js_namespace = ["window", "playground"], js_name = showError)]
|
||||
fn show_err(s: &str);
|
||||
}
|
||||
|
||||
/// Compiles the given directory into datapack files.
|
||||
|
@ -57,38 +60,38 @@ pub fn compile_zip(root_dir: JsValue) -> Option<String> {
|
|||
|
||||
// write each file to the zip archive
|
||||
for (path, file) in virtual_files {
|
||||
writer
|
||||
.start_file(path, SimpleFileOptions::default())
|
||||
.unwrap();
|
||||
writer.start_file(path, SimpleFileOptions::default()).ok()?;
|
||||
match file {
|
||||
VFile::Text(text) => {
|
||||
writer.write_all(text.as_bytes()).unwrap();
|
||||
writer.write_all(text.as_bytes()).ok()?;
|
||||
}
|
||||
VFile::Binary(data) => {
|
||||
writer.write_all(data).unwrap();
|
||||
writer.write_all(data).ok()?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
writer.set_comment("Data pack created with Shulkerscript web compiler");
|
||||
|
||||
writer.finish().unwrap();
|
||||
writer.finish().ok()?;
|
||||
|
||||
Some(BASE64_STANDARD.encode(buffer.into_inner()))
|
||||
}
|
||||
|
||||
fn _compile(root_dir: &VFolder) -> Result<VFolder> {
|
||||
colored::control::set_override(true);
|
||||
let printer = Printer::new();
|
||||
util::compile(&printer, root_dir, &get_script_paths(root_dir))
|
||||
let res = util::compile(&printer, root_dir, &get_script_paths(root_dir));
|
||||
printer.display();
|
||||
res
|
||||
}
|
||||
|
||||
struct Printer {
|
||||
printed: Cell<bool>,
|
||||
queue: Mutex<Vec<String>>,
|
||||
}
|
||||
impl<T: Display> Handler<T> for Printer {
|
||||
fn receive<E: Into<T>>(&self, error: E) {
|
||||
log_err(&error.into().to_string());
|
||||
self.printed.set(true);
|
||||
self.queue.lock().unwrap().push(format!("{}", error.into()));
|
||||
}
|
||||
|
||||
fn has_received(&self) -> bool {
|
||||
|
@ -99,12 +102,23 @@ impl Printer {
|
|||
/// Creates a new [`Printer`].
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
printed: Cell::new(false),
|
||||
queue: Mutex::new(Vec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
fn display(self) {
|
||||
let queue = self
|
||||
.queue
|
||||
.into_inner()
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(|el| ansi_to_html::convert(&el).unwrap())
|
||||
.collect::<Vec<_>>();
|
||||
show_err(&queue.join("\n\n"));
|
||||
}
|
||||
|
||||
fn has_printed(&self) -> bool {
|
||||
self.printed.get()
|
||||
!self.queue.lock().unwrap().is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue