/** * @license * Copyright 2023 Google LLC * SPDX-License-Identifier: Apache-2.0 */ import * as Blockly from 'blockly'; import * as newBlocks from './blocks'; import { javascriptGenerator } from 'blockly/javascript'; import { save, load } from './serialization'; import { toolbox } from './toolbox'; import { registerContinuousToolbox } from '@blockly/continuous-toolbox'; import Cookies from 'js-cookie'; import * as nano from 'nano'; import './index.css'; function randomValueHex(length: number) { let hex = ''; for (let i = 0; i < length; i++) hex += Math.floor(Math.random() * 256).toString(16); return hex; } let browserId = Cookies.get('id'); if (!browserId) { browserId = randomValueHex(24); if (!Cookies.get('id')) Cookies.set('id', browserId); } const blocks = Object.values(newBlocks).reduce((acc, val) => { acc = { ...acc, ...val.block }; return acc; }, {}); const generators = Object.values(newBlocks).reduce((acc, val) => { acc = { ...acc, [Object.keys(val.block)[0]]: val.toJS }; return acc; }, {}); // Register the blocks and generator with Blockly Blockly.common.defineBlocks(blocks); Object.assign(javascriptGenerator.forBlock, generators); registerContinuousToolbox(); // Set up UI elements and inject Blockly const codeDiv = document.getElementById('outputDiv')?.firstChild; const outputDiv = document.getElementById('output'); const blocklyDiv = document.getElementById('blocklyDiv'); if (!blocklyDiv) { throw new Error(`div with id 'blocklyDiv' not found`); } const ws = Blockly.inject( blocklyDiv, { toolbox, plugins: { flyoutsVerticalToolbox: 'ContinuousFlyout', metricsManager: 'ContinuousMetrics', toolbox: 'ContinuousToolbox', }, }, ); // This function resets the code and output divs, shows the // generated code from the workspace, and evals the code. // In a real application, you probably shouldn't use `eval`. const runCode = () => { const code = javascriptGenerator.workspaceToCode(ws as Blockly.Workspace); // console.dir(code); try { fetch( 'http://10.0.64.121:8081/set/' + browserId, { method: 'POST', body: code, } ); } catch (err) { window.alert('Error'); } if (codeDiv) codeDiv.textContent = code; // if (outputDiv) outputDiv.innerHTML = ''; // eval(code); }; if (ws) { (window as any)['ws'] = ws; (window as any)['save_ws'] = () => save(ws); // Load the initial state from storage and run the code. load(ws); runCode(); // Every time the workspace changes state, save the changes to storage. ws.addChangeListener((e: Blockly.Events.Abstract) => { // UI events are things like scrolling, zooming, etc. // No need to save after one of these. if (e.isUiEvent) return; save(ws); }); // Whenever the workspace changes meaningfully, run the code again. ws.addChangeListener((e: Blockly.Events.Abstract) => { // Don't run the code when the workspace finishes loading; we're // already running it once when the application starts. // Don't run the code during drags; we might have invalid state. if ( e.isUiEvent || e.type == Blockly.Events.FINISHED_LOADING || ws.isDragging() ) { return; } runCode(); }); }