Skip to content

Commit f6301a1

Browse files
author
Eric Thieme-Garmann
committed
ka
1 parent 53f1e20 commit f6301a1

File tree

4 files changed

+140
-123
lines changed

4 files changed

+140
-123
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"@blockly/plugin-scroll-options": "^6.0.9",
1414
"@blockly/plugin-typed-variable-modal": "^8.0.9",
1515
"@blockly/toolbox-search": "^2.0.12",
16-
"@blockly/workspace-backpack": "^6.0.9",
16+
"@blockly/workspace-backpack": "^7.0.0",
1717
"@blockly/workspace-minimap": "^0.2.9",
1818
"@blockly/zoom-to-fit": "^6.0.9",
1919
"@emotion/react": "^11.10.5",
Lines changed: 135 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import React, { Component } from "react";
1+
import React, { useEffect, useRef, useState } from "react";
22
import PropTypes from "prop-types";
3-
import { connect } from "react-redux";
3+
import { useSelector, useDispatch } from "react-redux";
44
import { onChangeWorkspace, clearStats } from "../../actions/workspaceActions";
55

66
import BlocklyComponent from "./BlocklyComponent";
@@ -13,144 +13,162 @@ import { ZoomToFitControl } from "@blockly/zoom-to-fit";
1313
import { initialXml } from "./initialXml.js";
1414
import { getMaxInstances } from "./helpers/maxInstances";
1515
import { Backpack } from "@blockly/workspace-backpack";
16+
import Snackbar from "../Snackbar";
1617

17-
class BlocklyWindow extends Component {
18-
constructor(props) {
19-
super(props);
20-
this.simpleWorkspace = React.createRef();
21-
}
18+
const BlocklyWindow = ({
19+
blockDisabled,
20+
readOnly = false,
21+
trashcan = true,
22+
zoomControls = true,
23+
grid: gridEnabled = true,
24+
move: moveEnabled = true,
25+
blocklyCSS,
26+
svg,
27+
initialXml: propsInitialXml,
28+
}) => {
29+
const dispatch = useDispatch();
30+
const renderer = useSelector((state) => state.general.renderer);
31+
const sounds = useSelector((state) => state.general.sounds);
32+
const language = useSelector((state) => state.general.language);
33+
const selectedBoard = useSelector((state) => state.board.board);
2234

23-
componentDidMount() {
35+
const simpleWorkspaceRef = useRef(null);
36+
const backpackRef = useRef(null);
37+
38+
const [snackbarOpen, setSnackbarOpen] = useState(false);
39+
const [snackInfo, setSnackInfo] = useState({
40+
type: "success",
41+
message: "",
42+
});
43+
const onBackPackChange = (event) => {
44+
if (event.type !== "backpack_change") {
45+
return;
46+
}
47+
setSnackInfo({
48+
type: "success",
49+
message: "Backpack changed",
50+
});
51+
setSnackbarOpen(true);
52+
};
53+
// Mount: setup workspace, listeners, zoom & backpack
54+
useEffect(() => {
2455
const workspace = Blockly.getMainWorkspace();
25-
this.props.onChangeWorkspace({});
26-
this.props.clearStats();
56+
57+
dispatch(onChangeWorkspace({}));
58+
dispatch(clearStats());
59+
60+
// Disable orphan blocks on every change
2761
workspace.addChangeListener(Blockly.Events.disableOrphans);
2862
workspace.addChangeListener((event) => {
29-
this.props.onChangeWorkspace(event);
30-
31-
// switch on that a block is displayed disabled or not depending on whether it is correctly connected
32-
// for SVG display, a deactivated block in the display is undesirable
33-
if (this.props.blockDisabled) {
63+
dispatch(onChangeWorkspace(event));
64+
if (blockDisabled) {
3465
Blockly.Events.disableOrphans(event);
3566
}
3667
});
68+
69+
// Resize & zoom-to-fit
3770
Blockly.svgResize(workspace);
3871
const zoomToFit = new ZoomToFitControl(workspace);
3972
zoomToFit.init();
4073

41-
// Initialize plugin.
4274
const backpack = new Backpack(workspace);
43-
4475
backpack.init();
45-
}
76+
workspace.addChangeListener(onBackPackChange);
77+
}, [dispatch, blockDisabled]);
4678

47-
componentDidUpdate(props) {
79+
// Update on board, initialXml or language change
80+
useEffect(() => {
4881
const workspace = Blockly.getMainWorkspace();
49-
var xml = this.props.initialXml;
50-
if (props.selectedBoard !== this.props.selectedBoard) {
51-
xml = localStorage.getItem("autoSaveXML");
52-
// change board
53-
if (!xml) xml = initialXml;
54-
var xmlDom = Blockly.utils.xml.textToDom(xml);
55-
Blockly.Xml.clearWorkspaceAndLoadFromXml(xmlDom, workspace);
82+
let xml = propsInitialXml;
83+
84+
// Board gewechselt?
85+
if (selectedBoard) {
86+
const saved = localStorage.getItem("autoSaveXML");
87+
xml = saved || initialXml;
88+
const dom = Blockly.utils.xml.textToDom(xml);
89+
Blockly.Xml.clearWorkspaceAndLoadFromXml(dom, workspace);
5690
}
5791

58-
// if svg is true, then the update process is done in the BlocklySvg component
59-
if (props.initialXml !== xml && !this.props.svg) {
60-
// guarantees that the current xml-code (this.props.initialXml) is rendered
92+
// Wenn wir nicht im SVG-Modus sind und initialXml sich geändert hat
93+
if (!svg && propsInitialXml) {
6194
workspace.clear();
62-
if (!xml) xml = initialXml;
63-
Blockly.Xml.domToWorkspace(Blockly.utils.xml.textToDom(xml), workspace);
95+
const dom = Blockly.utils.xml.textToDom(propsInitialXml);
96+
Blockly.Xml.domToWorkspace(dom, workspace);
6497
}
65-
if (props.language !== this.props.language) {
66-
// change language
67-
xml = localStorage.getItem("autoSaveXML");
68-
if (!xml) xml = initialXml;
69-
xmlDom = Blockly.utils.xml.textToDom(xml);
70-
Blockly.Xml.clearWorkspaceAndLoadFromXml(xmlDom, workspace);
71-
// var toolbox = workspace.getToolbox();
72-
// workspace.updateToolbox(toolbox.toolboxDef_);
98+
99+
// Sprache geändert?
100+
if (language) {
101+
const saved = localStorage.getItem("autoSaveXML");
102+
xml = saved || initialXml;
103+
const dom = Blockly.utils.xml.textToDom(xml);
104+
Blockly.Xml.clearWorkspaceAndLoadFromXml(dom, workspace);
73105
}
106+
107+
// Immer nach Update neu skalieren
74108
Blockly.svgResize(workspace);
75-
}
76-
77-
render() {
78-
return (
79-
<div>
80-
<BlocklyComponent
81-
ref={this.simpleWorkspace}
82-
style={this.props.svg ? { height: 0 } : this.props.blocklyCSS}
83-
readOnly={
84-
this.props.readOnly !== undefined ? this.props.readOnly : false
85-
}
86-
trashcan={
87-
this.props.trashcan !== undefined ? this.props.trashcan : true
88-
}
89-
renderer={this.props.renderer}
90-
sounds={this.props.sounds}
91-
maxInstances={getMaxInstances()}
92-
zoom={{
93-
// https://developers.google.com/blockly/guides/configure/web/zoom
94-
controls:
95-
this.props.zoomControls !== undefined
96-
? this.props.zoomControls
97-
: true,
98-
wheel: false,
99-
startScale: 1,
100-
maxScale: 3,
101-
minScale: 0.3,
102-
scaleSpeed: 1.2,
103-
}}
104-
grid={
105-
this.props.grid !== undefined && !this.props.grid
106-
? {}
107-
: {
108-
// https://developers.google.com/blockly/guides/configure/web/grid
109-
spacing: 20,
110-
length: 1,
111-
colour: "#4EAF47", // senseBox-green
112-
snap: false,
113-
}
114-
}
115-
media={"/media/blockly/"}
116-
move={
117-
this.props.move !== undefined && !this.props.move
118-
? {}
119-
: {
120-
// https://developers.google.com/blockly/guides/configure/web/move
121-
scrollbars: true,
122-
drag: true,
123-
wheel: true,
124-
}
125-
}
126-
initialXml={
127-
this.props.initialXml ? this.props.initialXml : initialXml
128-
}
129-
></BlocklyComponent>
130-
{this.props.svg && this.props.initialXml ? (
131-
<BlocklySvg initialXml={this.props.initialXml} />
132-
) : null}
133-
</div>
134-
);
135-
}
136-
}
109+
}, [selectedBoard, propsInitialXml, language, svg]);
137110

138-
BlocklyWindow.propTypes = {
139-
onChangeWorkspace: PropTypes.func.isRequired,
140-
clearStats: PropTypes.func.isRequired,
141-
renderer: PropTypes.string.isRequired,
142-
sounds: PropTypes.bool.isRequired,
143-
language: PropTypes.string.isRequired,
144-
selectedBoard: PropTypes.string.isRequired,
111+
// Grid- und Move-Konfiguration
112+
const gridConfig = gridEnabled
113+
? {
114+
spacing: 20,
115+
length: 1,
116+
colour: "#4EAF47",
117+
snap: false,
118+
}
119+
: {};
120+
const moveConfig = moveEnabled
121+
? {
122+
scrollbars: true,
123+
drag: true,
124+
wheel: true,
125+
}
126+
: {};
127+
128+
return (
129+
<div>
130+
<BlocklyComponent
131+
ref={simpleWorkspaceRef}
132+
style={svg ? { height: 0 } : blocklyCSS}
133+
readOnly={readOnly}
134+
trashcan={trashcan}
135+
renderer={renderer}
136+
sounds={sounds}
137+
maxInstances={getMaxInstances()}
138+
zoom={{
139+
controls: zoomControls,
140+
wheel: false,
141+
startScale: 1,
142+
maxScale: 3,
143+
minScale: 0.3,
144+
scaleSpeed: 1.2,
145+
}}
146+
grid={gridConfig}
147+
media="/media/blockly/"
148+
move={moveConfig}
149+
initialXml={propsInitialXml || initialXml}
150+
/>
151+
{svg && propsInitialXml && <BlocklySvg initialXml={propsInitialXml} />}
152+
<Snackbar
153+
open={snackbarOpen}
154+
message={snackInfo.message}
155+
type={snackInfo.type}
156+
key={snackInfo.key}
157+
/>
158+
</div>
159+
);
145160
};
146161

147-
const mapStateToProps = (state) => ({
148-
renderer: state.general.renderer,
149-
sounds: state.general.sounds,
150-
language: state.general.language,
151-
selectedBoard: state.board.board,
152-
});
162+
BlocklyWindow.propTypes = {
163+
blockDisabled: PropTypes.bool,
164+
readOnly: PropTypes.bool,
165+
trashcan: PropTypes.bool,
166+
zoomControls: PropTypes.bool,
167+
grid: PropTypes.bool,
168+
move: PropTypes.bool,
169+
blocklyCSS: PropTypes.object,
170+
svg: PropTypes.bool,
171+
initialXml: PropTypes.string,
172+
};
153173

154-
export default connect(mapStateToProps, { onChangeWorkspace, clearStats })(
155-
BlocklyWindow,
156-
);
174+
export default BlocklyWindow;

src/components/Settings/LanguageSelector.jsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ export default function LanguageSelector() {
7676
open={snackbarOpen}
7777
message={snackInfo.message}
7878
type={snackInfo.type}
79-
key={snackInfo.key}
8079
/>
8180
</div>
8281
);

yarn.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -312,10 +312,10 @@
312312
resolved "https://registry.yarnpkg.com/@blockly/toolbox-search/-/toolbox-search-2.0.16.tgz#b226097490fb9c69b79c7bee8f15d4644ed8b18d"
313313
integrity sha512-pg49w17DjV+BmjjRveMww1pGFm3ZKs6tX5oRnK0Uj5rCJIEWWIHsRpipcgZQ7U75vD2jFmvCVMzz0PZsPlhYvA==
314314

315-
"@blockly/workspace-backpack@^6.0.9":
316-
version "6.0.16"
317-
resolved "https://registry.yarnpkg.com/@blockly/workspace-backpack/-/workspace-backpack-6.0.16.tgz#9a96e009aa47c0b9c181fbb46b5533c23639838d"
318-
integrity sha512-jZZgThFkGEBGYcBtWzMTTFE3XkepqIBTTcLVKODhw5zPNABtGRwcys4wh/I7c925Wbbm+pKfDa3XdzjbgkQGVQ==
315+
"@blockly/workspace-backpack@^7.0.0":
316+
version "7.0.1"
317+
resolved "https://registry.yarnpkg.com/@blockly/workspace-backpack/-/workspace-backpack-7.0.1.tgz#342b97a5e7336876a4b695352b7a1cbecbcb5c7b"
318+
integrity sha512-kSl7CYTZ1aPvDX0vkkel8/KCMJjyYh7bHs3ZlWuKDAsCIuWpxZ4bcKawfCXIpw5V9dNAoiRAXEMEY0Vc6dn3Tw==
319319

320320
"@blockly/workspace-minimap@^0.2.9":
321321
version "0.2.16"

0 commit comments

Comments
 (0)