Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,816 changes: 996 additions & 820 deletions package-lock.json

Large diffs are not rendered by default.

42 changes: 21 additions & 21 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,35 +10,35 @@
"preview": "vite preview"
},
"dependencies": {
"@blockly/field-colour": "^4.0.0",
"@types/w3c-web-serial": "^1.0.3",
"axios": "^1.7.5",
"blockly": "^10.0.0",
"classnames": "^2.3.2",
"@blockly/field-colour": "^6.0.0",
"@types/w3c-web-serial": "^1.0.8",
"axios": "^1.12.2",
"blockly": "^12.3.1",
"classnames": "^2.5.1",
"jaculus-tools": "^0.0.23",
"react": "^18.2.0",
"react-blockly": "^7.2.2",
"react-dom": "^18.2.0",
"react": "^18.3.1",
"react-blockly": "^9.0.0",
"react-dom": "^18.3.1",
"react-syntax-highlighter": "^15.6.6",
"tailwind-override": "^0.6.1",
"typescript": "^5.1.6",
"typescript": "^5.9.3",
"util": "^0.12.5"
},
"devDependencies": {
"@types/node": "^20.4.1",
"@types/react": "^18.2.14",
"@types/react-dom": "^18.2.6",
"@types/react-syntax-highlighter": "^15.5.7",
"@vitejs/plugin-react": "^4.0.1",
"autoprefixer": "^10.4.14",
"eslint": "^8.44.0",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.1",
"postcss": "^8.4.25",
"tailwindcss": "^3.4.10",
"@types/react": "^19.2.2",
"@types/react-dom": "^19.2.1",
"@types/react-syntax-highlighter": "^15.5.13",
"@vitejs/plugin-react": "^5.0.4",
"autoprefixer": "^10.4.21",
"eslint": "^9.37.0",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^6.1.1",
"eslint-plugin-react-refresh": "^0.4.23",
"postcss": "^8.5.6",
"tailwindcss": "^3.4.18",
"vite": "^7.1.9",
"vite-plugin-checker": "^0.6.1",
"vite-plugin-checker": "^0.11.0",
"vite-plugin-node-polyfills": "^0.24.0"
}
}
2 changes: 1 addition & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ function App() {
return (
<DeviceProvider >
<GenerateCodeProvider>
<div className="flex flex-col h-full w-full">
<div className="flex flex-col h-full w-full light">
<Header />
<TopBar
currentWorkspaceJson={currentWorkspaceJson}
Expand Down
8 changes: 2 additions & 6 deletions src/components/buttons/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
import classNamesOriginal, {Argument} from "classnames";
import {overrideTailwindClasses} from "tailwind-override";
import {FC, InputHTMLAttributes} from "react";

export const classNamesOverride = (...args: Argument[]) =>
overrideTailwindClasses(classNamesOriginal(...args));
import { classNamesOverride } from "../../utils/classNamesOverride";
import { FC, InputHTMLAttributes } from "react";


export interface ButtonProps extends InputHTMLAttributes<HTMLInputElement> {
text: string,
classNames?: string,
onClick?: () => void,
active?: boolean,

}


Expand Down
3 changes: 2 additions & 1 deletion src/components/buttons/CopyBtn.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { FC, InputHTMLAttributes, useState } from "react";
import Button, { classNamesOverride } from "./Button";
import Button from "./Button";
import { classNamesOverride } from "../../utils/classNamesOverride";
import { useGenerateCode } from "../../context/GenerateCodeContext";

export interface CopyBtnProps extends InputHTMLAttributes<HTMLInputElement> {
Expand Down
3 changes: 2 additions & 1 deletion src/components/buttons/LoadBtn.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { FC, InputHTMLAttributes, useState } from "react";
import Button, { classNamesOverride } from "./Button";
import Button from "./Button";
import { classNamesOverride } from "../../utils/classNamesOverride";
import { loadWorkspaceFromFile, isValidWorkspaceJson } from "../../utils/blocklyStorage";

export interface LoadBtnProps extends InputHTMLAttributes<HTMLInputElement> {
Expand Down
3 changes: 2 additions & 1 deletion src/components/buttons/SaveBtn.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { FC, InputHTMLAttributes, useState } from "react";
import Button, { classNamesOverride } from "./Button";
import Button from "./Button";
import { classNamesOverride } from "../../utils/classNamesOverride";
import { saveWorkspaceToFile } from "../../utils/blocklyStorage";

export interface SaveBtnProps extends InputHTMLAttributes<HTMLInputElement> {
Expand Down
7 changes: 2 additions & 5 deletions src/components/labels/Label.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import classNamesOriginal, {Argument} from "classnames";
import {overrideTailwindClasses} from "tailwind-override";
import {FC, InputHTMLAttributes} from "react";

export const classNamesOverride = (...args: Argument[]) =>
overrideTailwindClasses(classNamesOriginal(...args));
import { classNamesOverride } from "../../utils/classNamesOverride";
import { FC, InputHTMLAttributes } from "react";


export interface LabelProps extends InputHTMLAttributes<HTMLInputElement> {
Expand Down
100 changes: 91 additions & 9 deletions src/components/topLevel/BlocklyEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import {FC, InputHTMLAttributes, useRef, useState, useEffect} from "react";
import {useGenerateCode} from "../../context/GenerateCodeContext";
import Blockly from "blockly";
import {javascriptGenerator} from "blockly/javascript";
import {BlocklyWorkspace} from "react-blockly";
import {javascriptGenerator as jsg} from "blockly/javascript";
import {BlocklyWorkspace, WorkspaceSvg} from "react-blockly";
import "./../../customBlocks/customBlocks";
import "../../styles/blockly-custom.css";

import {toolbox} from "../../customBlocks/toolbox";
export interface HeaderProps extends InputHTMLAttributes<HTMLInputElement> {
Expand All @@ -29,10 +29,10 @@ const BlocklyEditor: FC<HeaderProps> = ({ onWorkspaceChange, externalJson }) =>
}
}, [externalJson]);

const handleWorkspaceChange = (newWorkspace: Blockly.WorkspaceSvg) => {
const handleWorkspaceChange = (newWorkspace: WorkspaceSvg) => {
console.log("Workspace changed")
try {
let jsCode = javascriptGenerator.workspaceToCode(newWorkspace);
let jsCode = jsg.workspaceToCode(newWorkspace);
setCode(jsCode);
} catch (e) {
console.error("Error generating code: " + e);
Expand All @@ -52,17 +52,99 @@ const BlocklyEditor: FC<HeaderProps> = ({ onWorkspaceChange, externalJson }) =>
return (
<BlocklyWorkspace
key={workspaceKey} // Force re-mount when key changes
className="w-full h-full"
className="w-full h-full blockly-custom-theme"
toolboxConfiguration={toolbox}
onWorkspaceChange={handleWorkspaceChange}
initialJson={json}
onJsonChange={onJsonChange}
workspaceConfiguration={{
renderer: "zelos",
theme: {
name: "custom",
base: "classic", // Can be 'classic', 'modern', or 'deuteranopia'
componentStyles: {
workspaceBackgroundColour: "#f7fafc",
toolboxBackgroundColour: "#2d3748",
toolboxForegroundColour: "#f7fafc",
flyoutBackgroundColour: "#1a202c",
flyoutForegroundColour: "#f7fafc",
flyoutOpacity: 1,
scrollbarColour: "#4a5568",
insertionMarkerColour: "#60a5fa",
insertionMarkerOpacity: 0.3,
markerColour: "#60a5fa",
cursorColour: "#60a5fa"
},
blockStyles: {
logic_blocks: {
colourPrimary: "#615BA5",
colourSecondary: "#715CA5",
colourTertiary: "#5B4A95"
},
loop_blocks: {
colourPrimary: "#5B67A5",
colourSecondary: "#6B77B5",
colourTertiary: "#4B5795"
},
math_blocks: {
colourPrimary: "#5B80A5",
colourSecondary: "#6B90B5",
colourTertiary: "#4B7095"
},
text_blocks: {
colourPrimary: "#5BA55B",
colourSecondary: "#6BB56B",
colourTertiary: "#4B954B"
},
list_blocks: {
colourPrimary: "#5BA55B",
colourSecondary: "#6BB56B",
colourTertiary: "#4B954B"
},
variable_blocks: {
colourPrimary: "#A55B80",
colourSecondary: "#B56B90",
colourTertiary: "#954B70"
},
procedure_blocks: {
colourPrimary: "#995BA5",
colourSecondary: "#A96BB5",
colourTertiary: "#894B95"
}
},
categoryStyles: {
logic_category: {
colour: "#615BA5"
},
loop_category: {
colour: "#5B67A5"
},
math_category: {
colour: "#5B80A5"
},
text_category: {
colour: "#5BA55B"
},
list_category: {
colour: "#5BA55B"
},
variable_category: {
colour: "#A55B80"
},
procedure_category: {
colour: "#995BA5"
}
},
fontStyle: {
family: "Inter, system-ui, sans-serif",
weight: "normal",
size: 12
}
},
grid: {
spacing: 20,
length: 3,
colour: "#ccc",
colour: "#e2e8f0",
snap: true
},
zoom: {
Expand All @@ -71,8 +153,8 @@ const BlocklyEditor: FC<HeaderProps> = ({ onWorkspaceChange, externalJson }) =>
startScale: 1.0,
maxScale: 3,
minScale: 0.3,
scaleSpeed: 1.2
},
scaleSpeed: 1.1,
}
}}
/>
)
Expand Down
24 changes: 12 additions & 12 deletions src/components/topLevel/CodeResult.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
import {FC, InputHTMLAttributes} from "react";
import {useGenerateCode} from "../../context/GenerateCodeContext";
import { FC, InputHTMLAttributes } from "react";
import { useGenerateCode } from "../../context/GenerateCodeContext";
import SyntaxHighlighter from 'react-syntax-highlighter';
import { atomOneDark } from 'react-syntax-highlighter/dist/esm/styles/hljs';
import { atomOneDark as theme } from 'react-syntax-highlighter/dist/esm/styles/hljs';


theme.hljs.padding = "10px";

// @ts-expect-error
import {INITIAL_TOOLBOX_JSON} from "../../blockly-config";
import { INITIAL_TOOLBOX_JSON } from "../../blockly-config";

export interface CodeResultProps extends InputHTMLAttributes<HTMLInputElement> {
}


const CodeResult: FC<CodeResultProps> = ({}) => {
const {code} = useGenerateCode();
const CodeResult: FC<CodeResultProps> = ({ }) => {
const { code } = useGenerateCode();


return (
<div className="code-result w-full overflow-auto hide-scrollbar font-mono rounded">
<SyntaxHighlighter
language="javascript"
style={atomOneDark}
showLineNumbers
lineNumberContainerStyle={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', }}
lineNumberStyle={{ gridColumn: '1', minWidth: 'unset', width: '1.5em', textAlign: 'right', paddingRight: 'unset', marginRight: '1em', marginLeft: '0',}}
>
language="javascript"
style={theme}
showLineNumbers
>
{code}
</SyntaxHighlighter>
</div>
Expand Down
5 changes: 1 addition & 4 deletions src/components/topLevel/Monitor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@ import { Input } from "blockly";
import { ValueInput } from "blockly/core/inputs";
import Label from "../labels/Label";

import classNamesOriginal, {Argument} from "classnames";
import {overrideTailwindClasses} from "tailwind-override";

export const classNamesOverride = (...args: Argument[]) =>
overrideTailwindClasses(classNamesOriginal(...args));
import { classNamesOverride } from "../../utils/classNamesOverride";


export interface HeaderProps extends InputHTMLAttributes<HTMLInputElement> { }
Expand Down
22 changes: 11 additions & 11 deletions src/customBlocks/categories/ADC.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Blockly, { BlockSvg } from "blockly";
import { javascriptGenerator, Order } from "blockly/javascript";
import { CodeGenerator } from "blockly/core/generator";
import { Block, Blocks, FieldDropdown } from "blockly";
import { JavascriptGenerator as JsG, javascriptGenerator as jsg, Order } from "blockly/javascript";

import { toolbox } from "../toolbox";
import { addItemToToolbox, dummy, value, inline, output, color } from "../customBlocks";

Expand All @@ -12,16 +12,16 @@ addItemToToolbox(toolbox, "ADC",
},
);

Blockly.Blocks['adc_import'] = {
Blocks['adc_import'] = {
init: function () {
dummy(this, 'Import ADC');
inline(this);
color(this, "ADC");
}
}

javascriptGenerator.forBlock['adc_import'] = function (b: BlockSvg, g: CodeGenerator) {
return "import * as adc from 'adc';\n";
jsg.forBlock['adc_import'] = function (b: Block, g: JsG) {
return "import * as adc from 'adc';\n";
}

// ---- //
Expand All @@ -41,7 +41,7 @@ addItemToToolbox(toolbox, "ADC",
}
);

Blockly.Blocks['adc_configure'] = {
Blocks['adc_configure'] = {
init: function () {
dummy(this, 'Configure ADC');
value(this, "PIN", " pin:");
Expand All @@ -50,8 +50,8 @@ Blockly.Blocks['adc_configure'] = {
}
};

javascriptGenerator.forBlock['adc_configure'] = function (b: BlockSvg, g: CodeGenerator) {
return 'adc.configure(' + g.valueToCode(b, 'PIN', 0) + ');\n';
jsg.forBlock['adc_configure'] = function (b: Block, g: JsG) {
return 'adc.configure(' + g.valueToCode(b, 'PIN', 0) + ');\n';
}

// ---- //
Expand All @@ -71,7 +71,7 @@ addItemToToolbox(toolbox, "ADC",
},
);

Blockly.Blocks['adc_read'] = {
Blocks['adc_read'] = {
init: function () {
dummy(this, 'ADC read');
value(this, "PIN", " pin:");
Expand All @@ -80,6 +80,6 @@ Blockly.Blocks['adc_read'] = {
}
}

javascriptGenerator.forBlock['adc_read'] = function (b: BlockSvg, g: CodeGenerator) {
jsg.forBlock['adc_read'] = function (b: Block, g: JsG) {
return ['adc.read(' + g.valueToCode(b, 'PIN', 0) + ')', Order.NONE];
}
Loading