blockly-solidity / src / Blockly / BlocklyComponent.jsx
BlocklyComponent.jsx
Raw
/**
 * @license
 *
 * Copyright 2019 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @fileoverview Blockly React Component.
 * @author samelh@google.com (Sam El-Husseini)
 */

import React from "react"
import "./BlocklyComponent.css"
import { useEffect, useRef, useState } from "react"

import Blockly from "blockly/core"
import { Solidity } from "../generator/generator"
import locale from "blockly/msg/en"
import "blockly/blocks"

Blockly.setLocale(locale)

function BlocklyComponent(props) {
    const [javascriptCode, setJavascriptCode] = useState("")
    const blocklyDiv = useRef()
    const toolbox = useRef()
    let primaryWorkspace = useRef()
    
    const generateCode = () => {
        try {
            var code = Solidity.workspaceToCode(primaryWorkspace.current)
            setJavascriptCode(code)
        } catch (e) {
            setJavascriptCode(e)
        }
    }

    useEffect(() => {
        const { initialXml, children, ...rest } = props
        primaryWorkspace.current = Blockly.inject(blocklyDiv.current, {
            toolbox: toolbox.current,
            ...rest,
        })

        if (initialXml) {
            Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(initialXml), primaryWorkspace.current)
        }

        generateCode()

    }, [primaryWorkspace, toolbox, blocklyDiv, props])

    return (
        <React.Fragment>
            <div ref={blocklyDiv} className="fill-height" />
            <div style={{ display: "none", color: "black" }} ref={toolbox}>
                {props.children}
            </div>
            <textarea
                id="code"
                style={{ width: "calc(34% - 10px)", height: "600px", float: "right" }}
                value={javascriptCode}
                readOnly
            ></textarea>
            <button className="convertBtn" onClick={generateCode}>
                Convert
            </button>
        </React.Fragment>
    )
}

export default BlocklyComponent