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 ( <> Run {name} script You are about to run scripts provided by the developer of the hook, make sure you know what you are doing.
{templateError && ( Error occured while parsing template, modify script and try again! )}
{Object.keys(fields).length > 0 ? `You also need to fill in following parameters to run the script` : ""}
{Object.keys(fields).map((key) => ( {fields[key].attach === "account_secret" || fields[key].attach === "account_address" ? ( { setFields({ ...fields, [key]: { ...fields[key], value: e.target.value }, }); }} /> )} ))}
{iFrameCode && (