import * as Handlebars from "handlebars";
import { Play, X } from "phosphor-react";
import { useCallback, useEffect, useState } from "react";
import state, { IFile, ILog } from "../../state";
import Button from "../Button";
import Box from "../Box";
import Input from "../Input";
import Stack from "../Stack";
import {
Dialog,
DialogTrigger,
DialogContent,
DialogTitle,
DialogDescription,
DialogClose,
} from "../Dialog";
import Flex from "../Flex";
import { useSnapshot } from "valtio";
import Select from "../Select";
import { saveFile } from "../../state/actions/saveFile";
Handlebars.registerHelper(
"customize_input",
function (/* dynamic arguments */) {
return new Handlebars.SafeString(arguments[0]);
}
);
const generateHtmlTemplate = (code: string) => {
return `
`;
};
type Fields = Record<
string,
{
key: string;
value: string;
label?: string;
type?: string;
attach?: "account_secret" | "account_address" | string;
}
>;
const RunScript: React.FC<{ file: IFile }> = ({ file: { content, name } }) => {
const snap = useSnapshot(state);
const [templateError, setTemplateError] = useState("");
const getFieldValues = useCallback(() => {
try {
const parsed = Handlebars.parse(content);
const names = parsed.body
.filter((i) => i.type === "MustacheStatement")
.map((block) => {
// @ts-expect-error
const type = block.hash?.pairs?.find((i) => i.key == "type");
// @ts-expect-error
const attach = block.hash?.pairs?.find((i) => i.key == "attach");
// @ts-expect-error
const label = block.hash?.pairs?.find((i) => i.key == "label");
const key =
// @ts-expect-error
block?.path?.original === "customize_input"
? // @ts-expect-error
block?.params?.[0].original
: // @ts-expect-error
block?.path?.original;
return {
key,
label: label?.value?.original || key,
attach: attach?.value?.original,
type: type?.value?.original,
value: "",
};
});
const defaultState: Fields = {};
if (names) {
names.forEach((field) => (defaultState[field.key] = field));
}
setTemplateError("");
return defaultState;
} catch (err) {
console.log(err);
setTemplateError("Could not parse template");
return undefined;
}
}, [content]);
// const defaultFieldValues = getFieldValues();
const [fields, setFields] = useState({});
const [iFrameCode, setIframeCode] = useState("");
const [isDialogOpen, setIsDialogOpen] = useState(false);
const runScript = () => {
const fieldsToSend: Record = {};
Object.entries(fields).map(([key, obj]) => {
fieldsToSend[key] = obj.value;
});
const template = Handlebars.compile(content, { strict: false });
try {
const code = template(fieldsToSend);
setIframeCode(generateHtmlTemplate(code));
state.scriptLogs = [
...snap.scriptLogs,
{ type: "success", message: "Started running..." },
];
} catch (err) {
state.scriptLogs = [
...snap.scriptLogs,
// @ts-expect-error
{ type: "error", message: err?.message || "Could not parse template" },
];
}
};
useEffect(() => {
const handleEvent = (e: any) => {
if (e.data.type === "log" || e.data.type === "error") {
const data: ILog[] = e.data.args.map((msg: any) => ({
type: e.data.type,
message: typeof msg === "string" ? msg : JSON.stringify(msg, null, 2),
}));
state.scriptLogs = [...snap.scriptLogs, ...data];
}
};
window.addEventListener("message", handleEvent);
return () => window.removeEventListener("message", handleEvent);
}, [snap.scriptLogs]);
useEffect(() => {
const newDefaultState = getFieldValues();
setFields(newDefaultState || {});
}, [content, setFields, getFieldValues]);
const options = snap.accounts?.map((acc) => ({
label: acc.name,
secret: acc.secret,
address: acc.address,
value: acc.address,
}));
return (
<>
{iFrameCode && (
)}
>
);
};
export default RunScript;