From 45509774717efc96013447fd9673114b3de906e3 Mon Sep 17 00:00:00 2001
From: Delucse <46593742+Delucse@users.noreply.github.com>
Date: Tue, 15 Sep 2020 14:39:47 +0200
Subject: [PATCH] upload, download, compile and reset blocks
---
package.json | 1 +
src/components/ClearWorkspace.js | 46 ----------
src/components/Compile.js | 34 ++++++-
src/components/Home.js | 4 +-
src/components/Navbar.js | 2 -
src/components/WorkspaceFunc.js | 146 ++++++++++++++++++++++++++-----
6 files changed, 155 insertions(+), 78 deletions(-)
delete mode 100644 src/components/ClearWorkspace.js
diff --git a/package.json b/package.json
index ff3634c..9f78c9a 100644
--- a/package.json
+++ b/package.json
@@ -13,6 +13,7 @@
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
"blockly": "^3.20200625.2",
+ "file-saver": "^2.0.2",
"prismjs": "^1.20.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
diff --git a/src/components/ClearWorkspace.js b/src/components/ClearWorkspace.js
deleted file mode 100644
index 2e31b01..0000000
--- a/src/components/ClearWorkspace.js
+++ /dev/null
@@ -1,46 +0,0 @@
-import React, {Component} from 'react';
-import PropTypes from 'prop-types';
-import { connect } from 'react-redux';
-import { clearStats, onChangeCode } from '../actions/workspaceActions';
-import { initialXml } from './Blockly/initialXml.js';
-
-import * as Blockly from 'blockly/core';
-
-import ListItem from '@material-ui/core/ListItem';
-import ListItemIcon from '@material-ui/core/ListItemIcon';
-import ListItemText from '@material-ui/core/ListItemText';
-
-import { faTrashRestore } from "@fortawesome/free-solid-svg-icons";
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-
-class ClearWorkspace extends Component {
-
- clearWorkspace = () => {
- const workspace = Blockly.getMainWorkspace();
- Blockly.Events.disable(); // https://groups.google.com/forum/#!topic/blockly/m7e3g0TC75Y
- // if events are disabled, then the workspace will be cleared AND the blocks are not in the trashcan
- const xmlDom = Blockly.Xml.textToDom(initialXml)
- Blockly.Xml.clearWorkspaceAndLoadFromXml(xmlDom, workspace);
- Blockly.Events.enable();
- workspace.options.maxBlocks = Infinity;
- this.props.onChangeCode();
- this.props.clearStats();
- }
-
- render() {
- return (
- {this.clearWorkspace(); this.props.onClick();}}>
-
-
-
- );
- };
-}
-
-ClearWorkspace.propTypes = {
- clearStats: PropTypes.func.isRequired,
- onChangeCode: PropTypes.func.isRequired
-};
-
-
-export default connect(null, { clearStats, onChangeCode })(ClearWorkspace);
diff --git a/src/components/Compile.js b/src/components/Compile.js
index a6c86c2..e42f5cf 100644
--- a/src/components/Compile.js
+++ b/src/components/Compile.js
@@ -10,11 +10,26 @@ import DialogTitle from '@material-ui/core/DialogTitle';
import DialogContent from '@material-ui/core/DialogContent';
import DialogActions from '@material-ui/core/DialogActions';
import Dialog from '@material-ui/core/Dialog';
+import IconButton from '@material-ui/core/IconButton';
+import Tooltip from '@material-ui/core/Tooltip';
+
+import { faPlay } from "@fortawesome/free-solid-svg-icons";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
const styles = (theme) => ({
backdrop: {
zIndex: theme.zIndex.drawer + 1,
color: '#fff',
+ },
+ button: {
+ backgroundColor: theme.palette.primary.main,
+ color: theme.palette.primary.contrastText,
+ width: '40px',
+ height: '40px',
+ '&:hover': {
+ backgroundColor: theme.palette.primary.main,
+ color: theme.palette.primary.contrastText,
+ }
}
});
@@ -60,10 +75,21 @@ class Compile extends Component {
render() {
return (
-
-
+
+ {this.props.iconButton ?
+
+ this.compile()}
+ >
+
+
+
+ :
+
+ }
diff --git a/src/components/Home.js b/src/components/Home.js
index 5b6f71f..47555f9 100644
--- a/src/components/Home.js
+++ b/src/components/Home.js
@@ -72,7 +72,8 @@ class Home extends Component {
render() {
return (
-
+
+
@@ -93,7 +94,6 @@ class Home extends Component {
: null}
-
);
};
diff --git a/src/components/Navbar.js b/src/components/Navbar.js
index fb5365f..55db003 100644
--- a/src/components/Navbar.js
+++ b/src/components/Navbar.js
@@ -1,7 +1,6 @@
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
-import ClearWorkspace from './ClearWorkspace';
import senseboxLogo from './sensebox_logo.svg';
import { withRouter } from 'react-router-dom';
@@ -105,7 +104,6 @@ class Navbar extends Component {
))}
-
diff --git a/src/components/WorkspaceFunc.js b/src/components/WorkspaceFunc.js
index 8c4826c..117bf68 100644
--- a/src/components/WorkspaceFunc.js
+++ b/src/components/WorkspaceFunc.js
@@ -1,39 +1,143 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
+import { clearStats, onChangeCode } from '../actions/workspaceActions';
+
+import * as Blockly from 'blockly/core';
+
+import { saveAs } from 'file-saver';
+
+import { initialXml } from './Blockly/initialXml.js';
-import MaxBlocks from './MaxBlocks';
import Compile from './Compile';
+import { withStyles } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';
import DialogTitle from '@material-ui/core/DialogTitle';
import DialogContent from '@material-ui/core/DialogContent';
import DialogActions from '@material-ui/core/DialogActions';
import Dialog from '@material-ui/core/Dialog';
+import IconButton from '@material-ui/core/IconButton';
+import Tooltip from '@material-ui/core/Tooltip';
+
+import { faSave, faUpload, faShare } from "@fortawesome/free-solid-svg-icons";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+
+const styles = (theme) => ({
+ button: {
+ backgroundColor: theme.palette.primary.main,
+ color: theme.palette.primary.contrastText,
+ width: '40px',
+ height: '40px',
+ '&:hover': {
+ backgroundColor: theme.palette.primary.main,
+ color: theme.palette.primary.contrastText,
+ }
+ }
+});
+
class WorkspaceFunc extends Component {
- state = {
- title: '',
- content: '',
- open: false
- }
-
- getArduinoCode = () => {
- this.setState({ title: 'Adurino Code', content: this.props.arduino, open: true });
- }
-
- getXMLCode = () => {
- this.setState({ title: 'XML Code', content: this.props.xml, open: true });
+ constructor(props){
+ super(props);
+ this.inputRef = React.createRef();
+ this.state = {
+ title: '',
+ content: '',
+ open: false
+ };
}
toggleDialog = () => {
this.setState({ open: !this.state });
}
+ saveXmlFile = (code) => {
+ // saveTextFileAs
+ var fileName = 'todo.xml'
+ var blob = new Blob([code], { type: 'text/xml' });
+ saveAs(blob, fileName);
+ }
+
+ uploadXmlFile = (xmlFile) => {
+ console.log(xmlFile);
+ if(xmlFile.type !== 'text/xml'){
+ this.setState({ open: true, title: 'Unzulässiger Dateityp', content: 'Die übergebene Datei entsprach nicht dem geforderten Format. Es sind nur XML-Dateien zulässig.' });
+ }
+ else {
+ var reader = new FileReader();
+ reader.readAsText(xmlFile);
+ reader.onloadend = () => {
+ var xmlDom = null;
+ try {
+ xmlDom = Blockly.Xml.textToDom(reader.result);
+ const workspace = Blockly.getMainWorkspace();
+ var xmlBefore = this.props.xml;
+ workspace.clear();
+ this.props.clearStats();
+ Blockly.Xml.domToWorkspace(xmlDom, workspace);
+ if(workspace.getAllBlocks().length < 1){
+ Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xmlBefore), workspace)
+ this.setState({ open: true, title: 'Keine Blöcke', content: 'Es wurden keine Blöcke detektiert. Bitte überprüfe den XML-Code und versuche es erneut.' });
+ }
+ } catch(err){
+ this.setState({ open: true, title: 'Ungültige XML', content: 'Die XML-Datei konnte nicht in Blöcke zerlegt werden. Bitte überprüfe den XML-Code und versuche es erneut.' });
+ }
+ };
+ }
+ }
+
+ resetWorkspace = () => {
+ const workspace = Blockly.getMainWorkspace();
+ Blockly.Events.disable(); // https://groups.google.com/forum/#!topic/blockly/m7e3g0TC75Y
+ // if events are disabled, then the workspace will be cleared AND the blocks are not in the trashcan
+ const xmlDom = Blockly.Xml.textToDom(initialXml)
+ Blockly.Xml.clearWorkspaceAndLoadFromXml(xmlDom, workspace);
+ Blockly.Events.enable();
+ workspace.options.maxBlocks = Infinity;
+ this.props.onChangeCode();
+ this.props.clearStats();
+ }
+
render() {
return (
-
+
+
+
+ this.saveXmlFile(this.props.xml)}
+ >
+
+
+
+
+
{this.uploadXmlFile(e.target.files[0])}}
+ id="open-blocks"
+ type="file"
+ />
+
+
+
+ this.resetWorkspace()}
+ >
+
+
+
-
-
-
-
);
};
@@ -60,7 +156,9 @@ class WorkspaceFunc extends Component {
WorkspaceFunc.propTypes = {
arduino: PropTypes.string.isRequired,
- xml: PropTypes.string.isRequired
+ xml: PropTypes.string.isRequired,
+ clearStats: PropTypes.func.isRequired,
+ onChangeCode: PropTypes.func.isRequired
};
const mapStateToProps = state => ({
@@ -68,4 +166,4 @@ const mapStateToProps = state => ({
xml: state.workspace.code.xml
});
-export default connect(mapStateToProps, null)(WorkspaceFunc);
+export default connect(mapStateToProps, { clearStats, onChangeCode })(withStyles(styles, {withTheme: true})(WorkspaceFunc));