import Editor, { loader } from "@monaco-editor/react"; import { FC, useEffect, useState } from "react"; import { useTheme } from "next-themes"; import dark from "../../theme/editor/amy.json"; import light from "../../theme/editor/xcode_default.json"; import { useSnapshot } from "valtio"; import state, { parseJSON, prepareState, TransactionState } from "../../state"; import Text from "../Text"; import Flex from "../Flex"; import { Link } from ".."; import { showAlert } from "../../state/actions/showAlert"; loader.config({ paths: { vs: "https://cdn.jsdelivr.net/npm/monaco-editor@0.30.1/min/vs", }, }); interface JsonProps { value?: string; header?: string; setState: (pTx?: Partial | undefined) => void; state: TransactionState; } export const TxJson: FC = ({ value = "", state: txState, header, setState, }) => { const { editorSettings } = useSnapshot(state); const { editorValue = value } = txState; const { theme } = useTheme(); const [hasUnsaved, setHasUnsaved] = useState(false); useEffect(() => { setState({ editorValue: value }); // eslint-disable-next-line react-hooks/exhaustive-deps }, [value]); useEffect(() => { if (editorValue === value) setHasUnsaved(false); else setHasUnsaved(true); }, [editorValue, value]); const saveState = (value: string, txState: TransactionState) => { const tx = prepareState(value, txState); if (tx) setState(tx); }; const discardChanges = () => { showAlert("Confirm", { body: "Are you sure to discard these changes?", confirmText: "Yes", onConfirm: () => setState({ editorValue: value }), }); }; const onExit = (value: string) => { const options = parseJSON(value); if (options) { saveState(value, txState); return; } showAlert("Error!", { body: `Malformed Transaction in ${header}, would you like to discard these changes?`, confirmText: "Discard", onConfirm: () => setState({ editorValue: value }), onCancel: () => setState({ viewType: "json", editorSavedValue: value }), }); }; const path = `file:///${header}`; return ( { monaco.editor.defineTheme("dark", dark as any); monaco.editor.defineTheme("light", light as any); }} value={editorValue} onChange={val => setState({ editorValue: val })} onMount={(editor, monaco) => { editor.updateOptions({ minimap: { enabled: false }, glyphMargin: true, tabSize: editorSettings.tabSize, dragAndDrop: true, fontSize: 14, }); const model = editor.getModel(); model?.onWillDispose(() => onExit(model.getValue())); }} theme={theme === "dark" ? "dark" : "light"} /> {hasUnsaved && ( This file has unsaved changes.{" "} saveState(editorValue, txState)}>save{" "} discard )} ); };