add block sharing
This commit is contained in:
parent
0cb7bba521
commit
e647d6e58e
1
.env
1
.env
@ -1,2 +1,3 @@
|
|||||||
REACT_APP_COMPILER_URL=https://compiler.sensebox.de
|
REACT_APP_COMPILER_URL=https://compiler.sensebox.de
|
||||||
REACT_APP_BOARD=sensebox-mcu
|
REACT_APP_BOARD=sensebox-mcu
|
||||||
|
REACT_APP_BLOCKLY_API=http://46.101.243.134:3000
|
||||||
|
32
package-lock.json
generated
32
package-lock.json
generated
@ -8720,6 +8720,11 @@
|
|||||||
"minimist": "^1.2.5"
|
"minimist": "^1.2.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"mnemonic-id": {
|
||||||
|
"version": "3.2.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/mnemonic-id/-/mnemonic-id-3.2.7.tgz",
|
||||||
|
"integrity": "sha512-kysx9gAGbvrzuFYxKkcRjnsg/NK61ovJOV4F1cHTRl9T5leg+bo6WI0pWIvOFh1Z/yDL0cjA5R3EEGPPLDv/XA=="
|
||||||
|
},
|
||||||
"moment": {
|
"moment": {
|
||||||
"version": "2.29.0",
|
"version": "2.29.0",
|
||||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.0.tgz",
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.0.tgz",
|
||||||
@ -11394,6 +11399,13 @@
|
|||||||
"tough-cookie": "~2.5.0",
|
"tough-cookie": "~2.5.0",
|
||||||
"tunnel-agent": "^0.6.0",
|
"tunnel-agent": "^0.6.0",
|
||||||
"uuid": "^3.3.2"
|
"uuid": "^3.3.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"uuid": {
|
||||||
|
"version": "3.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||||
|
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"request-promise-core": {
|
"request-promise-core": {
|
||||||
@ -12125,6 +12137,13 @@
|
|||||||
"requires": {
|
"requires": {
|
||||||
"faye-websocket": "^0.10.0",
|
"faye-websocket": "^0.10.0",
|
||||||
"uuid": "^3.0.1"
|
"uuid": "^3.0.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"uuid": {
|
||||||
|
"version": "3.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||||
|
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sockjs-client": {
|
"sockjs-client": {
|
||||||
@ -13269,9 +13288,9 @@
|
|||||||
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
|
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
|
||||||
},
|
},
|
||||||
"uuid": {
|
"uuid": {
|
||||||
"version": "3.4.0",
|
"version": "8.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz",
|
||||||
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
"integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg=="
|
||||||
},
|
},
|
||||||
"v8-compile-cache": {
|
"v8-compile-cache": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
@ -13929,6 +13948,13 @@
|
|||||||
"requires": {
|
"requires": {
|
||||||
"ansi-colors": "^3.0.0",
|
"ansi-colors": "^3.0.0",
|
||||||
"uuid": "^3.3.2"
|
"uuid": "^3.3.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"uuid": {
|
||||||
|
"version": "3.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||||
|
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"webpack-manifest-plugin": {
|
"webpack-manifest-plugin": {
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
"@testing-library/user-event": "^7.2.1",
|
"@testing-library/user-event": "^7.2.1",
|
||||||
"blockly": "^3.20200924.0",
|
"blockly": "^3.20200924.0",
|
||||||
"file-saver": "^2.0.2",
|
"file-saver": "^2.0.2",
|
||||||
|
"mnemonic-id": "^3.2.7",
|
||||||
"moment": "^2.28.0",
|
"moment": "^2.28.0",
|
||||||
"prismjs": "^1.20.0",
|
"prismjs": "^1.20.0",
|
||||||
"react": "^16.13.1",
|
"react": "^16.13.1",
|
||||||
@ -23,7 +24,8 @@
|
|||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^5.2.0",
|
||||||
"react-scripts": "3.4.1",
|
"react-scripts": "3.4.1",
|
||||||
"redux": "^4.0.5",
|
"redux": "^4.0.5",
|
||||||
"redux-thunk": "^2.3.0"
|
"redux-thunk": "^2.3.0",
|
||||||
|
"uuid": "^8.3.1"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"start": "react-scripts start",
|
||||||
|
@ -6,7 +6,7 @@ import clsx from 'clsx';
|
|||||||
|
|
||||||
import Breadcrumbs from '../Breadcrumbs';
|
import Breadcrumbs from '../Breadcrumbs';
|
||||||
|
|
||||||
import gallery from './gallery.json';
|
// import gallery from './gallery.json';
|
||||||
// import tutorials from '../../data/tutorials.json';
|
// import tutorials from '../../data/tutorials.json';
|
||||||
|
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
@ -49,8 +49,24 @@ const styles = (theme) => ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class GalleryHome extends Component {
|
class GalleryHome extends Component {
|
||||||
|
|
||||||
|
state = {
|
||||||
|
gallery: []
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
console.log(process.env.REACT_APP_BLOCKLY_API)
|
||||||
|
fetch(process.env.REACT_APP_BLOCKLY_API + this.props.location.pathname)
|
||||||
|
.then(res => res.json())
|
||||||
|
.then((data) => {
|
||||||
|
this.setState({ gallery: data })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@ -58,7 +74,7 @@ class GalleryHome extends Component {
|
|||||||
|
|
||||||
<h1>Gallery</h1>
|
<h1>Gallery</h1>
|
||||||
<Grid container spacing={2}>
|
<Grid container spacing={2}>
|
||||||
{gallery.map((gallery, i) => {
|
{this.state.gallery.map((gallery, i) => {
|
||||||
return (
|
return (
|
||||||
<Grid item xs={12} sm={6} md={4} xl={3} key={i} style={{}}>
|
<Grid item xs={12} sm={6} md={4} xl={3} key={i} style={{}}>
|
||||||
<Link to={`/gallery/${gallery.id}`} style={{ textDecoration: 'none', color: 'inherit' }}>
|
<Link to={`/gallery/${gallery.id}`} style={{ textDecoration: 'none', color: 'inherit' }}>
|
||||||
|
@ -10,6 +10,7 @@ import WorkspaceFunc from './WorkspaceFunc';
|
|||||||
import BlocklyWindow from './Blockly/BlocklyWindow';
|
import BlocklyWindow from './Blockly/BlocklyWindow';
|
||||||
import CodeViewer from './CodeViewer';
|
import CodeViewer from './CodeViewer';
|
||||||
import TrashcanButtons from './TrashcanButtons';
|
import TrashcanButtons from './TrashcanButtons';
|
||||||
|
import { createNameId } from 'mnemonic-id';
|
||||||
|
|
||||||
import Grid from '@material-ui/core/Grid';
|
import Grid from '@material-ui/core/Grid';
|
||||||
import IconButton from '@material-ui/core/IconButton';
|
import IconButton from '@material-ui/core/IconButton';
|
||||||
@ -18,7 +19,6 @@ import { withStyles } from '@material-ui/core/styles';
|
|||||||
|
|
||||||
import { faCode } from "@fortawesome/free-solid-svg-icons";
|
import { faCode } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import gallery from './Gallery/gallery.json';
|
|
||||||
|
|
||||||
const styles = (theme) => ({
|
const styles = (theme) => ({
|
||||||
codeOn: {
|
codeOn: {
|
||||||
@ -46,11 +46,19 @@ class Home extends Component {
|
|||||||
|
|
||||||
state = {
|
state = {
|
||||||
codeOn: false,
|
codeOn: false,
|
||||||
|
gallery: [],
|
||||||
|
share: [],
|
||||||
projectToLoad: undefined
|
projectToLoad: undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.setState({ projectToLoad: gallery.find(project => project.id == this.props.match.params.galleryId) })
|
|
||||||
|
this.props.workspaceName(createNameId());
|
||||||
|
fetch(process.env.BLOCKLY_API + this.props.location.pathname)
|
||||||
|
.then(res => res.json())
|
||||||
|
.then((data) => {
|
||||||
|
this.setState({ projectToLoad: data })
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -85,6 +93,7 @@ class Home extends Component {
|
|||||||
if (this.state.projectToLoad) {
|
if (this.state.projectToLoad) {
|
||||||
console.log(this.state.projectToLoad.xml)
|
console.log(this.state.projectToLoad.xml)
|
||||||
}
|
}
|
||||||
|
console.log(this.props);
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div style={{ float: 'right', height: '40px', marginBottom: '20px' }}><WorkspaceFunc /></div>
|
<div style={{ float: 'right', height: '40px', marginBottom: '20px' }}><WorkspaceFunc /></div>
|
||||||
|
@ -20,6 +20,7 @@ class Routes extends Component {
|
|||||||
<Route path="/tutorial" exact component={TutorialHome} />
|
<Route path="/tutorial" exact component={TutorialHome} />
|
||||||
<Route path="/gallery" exact component={GalleryHome} />
|
<Route path="/gallery" exact component={GalleryHome} />
|
||||||
<Route path="/gallery/:galleryId" exact component={Home} />
|
<Route path="/gallery/:galleryId" exact component={Home} />
|
||||||
|
<Route path="/share/:shareId" exact component={Home} />
|
||||||
<Route path="/tutorial/builder" exact component={Builder} />
|
<Route path="/tutorial/builder" exact component={Builder} />
|
||||||
<Route path="/tutorial/:tutorialId" exact component={Tutorial} />
|
<Route path="/tutorial/:tutorialId" exact component={Tutorial} />
|
||||||
<Route component={NotFound} />
|
<Route component={NotFound} />
|
||||||
|
@ -12,7 +12,6 @@ import { initialXml } from './Blockly/initialXml.js';
|
|||||||
|
|
||||||
import Compile from './Compile';
|
import Compile from './Compile';
|
||||||
import SolutionCheck from './Tutorial/SolutionCheck';
|
import SolutionCheck from './Tutorial/SolutionCheck';
|
||||||
import Dialog from './Dialog';
|
|
||||||
import Snackbar from './Snackbar';
|
import Snackbar from './Snackbar';
|
||||||
|
|
||||||
import withWidth, { isWidthDown } from '@material-ui/core/withWidth';
|
import withWidth, { isWidthDown } from '@material-ui/core/withWidth';
|
||||||
@ -22,8 +21,19 @@ import IconButton from '@material-ui/core/IconButton';
|
|||||||
import Tooltip from '@material-ui/core/Tooltip';
|
import Tooltip from '@material-ui/core/Tooltip';
|
||||||
import TextField from '@material-ui/core/TextField';
|
import TextField from '@material-ui/core/TextField';
|
||||||
import Typography from '@material-ui/core/Typography';
|
import Typography from '@material-ui/core/Typography';
|
||||||
|
import { createId } from 'mnemonic-id';
|
||||||
|
|
||||||
import { faPen, faSave, faUpload, faCamera, faShare } from "@fortawesome/free-solid-svg-icons";
|
|
||||||
|
import Dialog from './Dialog';
|
||||||
|
// import Dialog from '@material-ui/core/Dialog';
|
||||||
|
import DialogActions from '@material-ui/core/DialogActions';
|
||||||
|
import DialogContent from '@material-ui/core/DialogContent';
|
||||||
|
import DialogContentText from '@material-ui/core/DialogContentText';
|
||||||
|
import DialogTitle from '@material-ui/core/DialogTitle';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import { faPen, faSave, faUpload, faCamera, faShare, faShareAlt } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
|
|
||||||
const styles = (theme) => ({
|
const styles = (theme) => ({
|
||||||
@ -49,9 +59,10 @@ const styles = (theme) => ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class WorkspaceFunc extends Component {
|
class WorkspaceFunc extends Component {
|
||||||
|
|
||||||
constructor(props){
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.inputRef = React.createRef();
|
this.inputRef = React.createRef();
|
||||||
this.state = {
|
this.state = {
|
||||||
@ -60,21 +71,25 @@ class WorkspaceFunc extends Component {
|
|||||||
open: false,
|
open: false,
|
||||||
file: false,
|
file: false,
|
||||||
saveFile: false,
|
saveFile: false,
|
||||||
|
share: false,
|
||||||
name: props.name,
|
name: props.name,
|
||||||
snackbar: false,
|
snackbar: false,
|
||||||
key: '',
|
key: '',
|
||||||
message: ''
|
message: '',
|
||||||
|
id: ''
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(props){
|
|
||||||
if(props.name !== this.props.name){
|
|
||||||
this.setState({name: this.props.name});
|
componentDidUpdate(props) {
|
||||||
|
if (props.name !== this.props.name) {
|
||||||
|
this.setState({ name: this.props.name });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleDialog = () => {
|
toggleDialog = () => {
|
||||||
this.setState({ open: !this.state });
|
this.setState({ open: !this.state, share: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
saveXmlFile = () => {
|
saveXmlFile = () => {
|
||||||
@ -87,6 +102,41 @@ class WorkspaceFunc extends Component {
|
|||||||
saveAs(blob, fileName);
|
saveAs(blob, fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shareBlocks = () => {
|
||||||
|
let code = this.props.xml;
|
||||||
|
let requestOptions = '';
|
||||||
|
let id = '';
|
||||||
|
if (this.state.id !== '') {
|
||||||
|
requestOptions = {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({
|
||||||
|
id: this.state.id,
|
||||||
|
name: this.state.name,
|
||||||
|
xml: code
|
||||||
|
})
|
||||||
|
};
|
||||||
|
fetch(process.env.BLOCKLY_API + '/share' + this.state.id, requestOptions)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => this.setState({ share: true }));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
id = createId(10);
|
||||||
|
requestOptions = {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({
|
||||||
|
id: id,
|
||||||
|
name: this.state.name,
|
||||||
|
xml: code
|
||||||
|
})
|
||||||
|
};
|
||||||
|
fetch(process.env.BLOCKLY_API + '/share', requestOptions)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => this.setState({ id: data.id, share: true }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getSvg = () => {
|
getSvg = () => {
|
||||||
const workspace = Blockly.getMainWorkspace();
|
const workspace = Blockly.getMainWorkspace();
|
||||||
var canvas = workspace.svgBlockCanvas_.cloneNode(true);
|
var canvas = workspace.svgBlockCanvas_.cloneNode(true);
|
||||||
@ -98,7 +148,7 @@ class WorkspaceFunc extends Component {
|
|||||||
// var cssContent = Blockly.Css.CONTENT.join('');
|
// var cssContent = Blockly.Css.CONTENT.join('');
|
||||||
var cssContent = '';
|
var cssContent = '';
|
||||||
for (var i = 0; i < document.getElementsByTagName('style').length; i++) {
|
for (var i = 0; i < document.getElementsByTagName('style').length; i++) {
|
||||||
if(/^blockly.*$/.test(document.getElementsByTagName('style')[i].id)){
|
if (/^blockly.*$/.test(document.getElementsByTagName('style')[i].id)) {
|
||||||
cssContent += document.getElementsByTagName('style')[i].firstChild.data.replace(/\..* \./g, '.');
|
cssContent += document.getElementsByTagName('style')[i].firstChild.data.replace(/\..* \./g, '.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,22 +175,22 @@ class WorkspaceFunc extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createFileName = (filetype) => {
|
createFileName = (filetype) => {
|
||||||
this.setState({file: filetype}, () => {
|
this.setState({ file: filetype }, () => {
|
||||||
if(this.state.name){
|
if (this.state.name) {
|
||||||
this.state.file === 'xml' ? this.saveXmlFile() : this.getSvg()
|
this.state.file === 'xml' ? this.saveXmlFile() : this.getSvg()
|
||||||
}
|
}
|
||||||
else{
|
else {
|
||||||
this.setState({ saveFile: true, file: filetype, open: true, title: this.state.file === 'xml' ? 'Blöcke speichern' : 'Screenshot erstellen', content: `Bitte gib einen Namen für die Bennenung der ${this.state.file === 'xml' ? 'XML' : 'SVG'}-Datei ein und bestätige diesen mit einem Klick auf 'Eingabe'.` });
|
this.setState({ saveFile: true, file: filetype, open: true, title: this.state.file === 'xml' ? 'Blöcke speichern' : 'Screenshot erstellen', content: `Bitte gib einen Namen für die Bennenung der ${this.state.file === 'xml' ? 'XML' : 'SVG'}-Datei ein und bestätige diesen mit einem Klick auf 'Eingabe'.` });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setFileName = (e) => {
|
setFileName = (e) => {
|
||||||
this.setState({name: e.target.value});
|
this.setState({ name: e.target.value });
|
||||||
}
|
}
|
||||||
|
|
||||||
uploadXmlFile = (xmlFile) => {
|
uploadXmlFile = (xmlFile) => {
|
||||||
if(xmlFile.type !== 'text/xml'){
|
if (xmlFile.type !== 'text/xml') {
|
||||||
this.setState({ open: true, file: false, title: 'Unzulässiger Dateityp', content: 'Die übergebene Datei entsprach nicht dem geforderten Format. Es sind nur XML-Dateien zulässig.' });
|
this.setState({ open: true, file: false, title: 'Unzulässiger Dateityp', content: 'Die übergebene Datei entsprach nicht dem geforderten Format. Es sind nur XML-Dateien zulässig.' });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -155,18 +205,18 @@ class WorkspaceFunc extends Component {
|
|||||||
workspace.clear();
|
workspace.clear();
|
||||||
this.props.clearStats();
|
this.props.clearStats();
|
||||||
Blockly.Xml.domToWorkspace(xmlDom, workspace);
|
Blockly.Xml.domToWorkspace(xmlDom, workspace);
|
||||||
if(workspace.getAllBlocks().length < 1){
|
if (workspace.getAllBlocks().length < 1) {
|
||||||
Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xmlBefore), workspace)
|
Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xmlBefore), workspace)
|
||||||
this.setState({ open: true, file: false, title: 'Keine Blöcke', content: 'Es wurden keine Blöcke detektiert. Bitte überprüfe den XML-Code und versuche es erneut.' });
|
this.setState({ open: true, file: false, title: 'Keine Blöcke', content: 'Es wurden keine Blöcke detektiert. Bitte überprüfe den XML-Code und versuche es erneut.' });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(!this.props.solutionCheck){
|
if (!this.props.solutionCheck) {
|
||||||
var extensionPosition = xmlFile.name.lastIndexOf('.');
|
var extensionPosition = xmlFile.name.lastIndexOf('.');
|
||||||
this.props.workspaceName(xmlFile.name.substr(0, extensionPosition));
|
this.props.workspaceName(xmlFile.name.substr(0, extensionPosition));
|
||||||
}
|
}
|
||||||
this.setState({ snackbar: true, key: Date.now(), message: 'Das Projekt aus gegebener XML-Datei wurde erfolgreich eingefügt.' });
|
this.setState({ snackbar: true, key: Date.now(), message: 'Das Projekt aus gegebener XML-Datei wurde erfolgreich eingefügt.' });
|
||||||
}
|
}
|
||||||
} catch(err){
|
} catch (err) {
|
||||||
this.setState({ open: true, file: false, 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.' });
|
this.setState({ open: true, file: false, 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.' });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -189,56 +239,60 @@ class WorkspaceFunc extends Component {
|
|||||||
workspace.options.maxBlocks = Infinity;
|
workspace.options.maxBlocks = Infinity;
|
||||||
this.props.onChangeCode();
|
this.props.onChangeCode();
|
||||||
this.props.clearStats();
|
this.props.clearStats();
|
||||||
if(!this.props.solutionCheck){
|
if (!this.props.solutionCheck) {
|
||||||
this.props.workspaceName(null);
|
this.props.workspaceName(null);
|
||||||
}
|
}
|
||||||
this.setState({ snackbar: true, key: Date.now(), message: 'Das Projekt wurde erfolgreich zurückgesetzt.' });
|
this.setState({ snackbar: true, key: Date.now(), message: 'Das Projekt wurde erfolgreich zurückgesetzt.' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div style={{width: 'max-content', display: 'flex'}}>
|
<div style={{ width: 'max-content', display: 'flex' }}>
|
||||||
{!this.props.solutionCheck ?
|
{!this.props.solutionCheck ?
|
||||||
<Tooltip title={`Name des Projekts${this.props.name ? `: ${this.props.name}` : ''}`} arrow style={{marginRight: '5px'}}>
|
<Tooltip title={`Name des Projekts${this.props.name ? `: ${this.props.name}` : ''}`} arrow style={{ marginRight: '5px' }}>
|
||||||
<div className={this.props.classes.workspaceName} onClick={() => {this.setState({file: true, open: true, saveFile: false, title: 'Projekt benennen', content: 'Bitte gib einen Namen für das Projekt ein und bestätige diesen mit einem Klick auf \'Eingabe\'.'})}}>
|
<div className={this.props.classes.workspaceName} onClick={() => { this.setState({ file: true, open: true, saveFile: false, title: 'Projekt benennen', content: 'Bitte gib einen Namen für das Projekt ein und bestätige diesen mit einem Klick auf \'Eingabe\'.' }) }}>
|
||||||
{this.props.name && !isWidthDown('xs', this.props.width) ? <Typography style={{margin: 'auto -3px auto 12px'}}>{this.props.name}</Typography> : null}
|
{this.props.name && !isWidthDown('xs', this.props.width) ? <Typography style={{ margin: 'auto -3px auto 12px' }}>{this.props.name}</Typography> : null}
|
||||||
<div style={{width: '40px', display: 'flex'}}>
|
<div style={{ width: '40px', display: 'flex' }}>
|
||||||
<FontAwesomeIcon icon={faPen} style={{height: '18px', width: '18px', margin: 'auto'}}/>
|
<FontAwesomeIcon icon={faPen} style={{ height: '18px', width: '18px', margin: 'auto' }} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
: null}
|
: null}
|
||||||
{this.props.solutionCheck ? <SolutionCheck /> : <Compile iconButton />}
|
{this.props.solutionCheck ? <SolutionCheck /> : <Compile iconButton />}
|
||||||
<Tooltip title='Blöcke speichern' arrow style={{marginRight: '5px'}}>
|
<Tooltip title='Blöcke speichern' arrow style={{ marginRight: '5px' }}>
|
||||||
<IconButton
|
<IconButton
|
||||||
className={this.props.classes.button}
|
className={this.props.classes.button}
|
||||||
onClick={() => {this.createFileName('xml');}}
|
onClick={() => { this.createFileName('xml'); }}
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon icon={faSave} size="xs"/>
|
<FontAwesomeIcon icon={faSave} size="xs" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<div ref={this.inputRef} style={{width: 'max-content', height: '40px', marginRight: '5px'}}>
|
<div ref={this.inputRef} style={{ width: 'max-content', height: '40px', marginRight: '5px' }}>
|
||||||
<input
|
<input
|
||||||
style={{display: 'none'}}
|
style={{ display: 'none' }}
|
||||||
accept="text/xml"
|
accept="text/xml"
|
||||||
onChange={(e) => {this.uploadXmlFile(e.target.files[0])}}
|
onChange={(e) => { this.uploadXmlFile(e.target.files[0]) }}
|
||||||
id="open-blocks"
|
id="open-blocks"
|
||||||
type="file"
|
type="file"
|
||||||
/>
|
/>
|
||||||
<label htmlFor="open-blocks">
|
<label htmlFor="open-blocks">
|
||||||
<Tooltip title='Blöcke öffnen' arrow style={{marginRight: '5px'}}>
|
<Tooltip title='Blöcke öffnen' arrow style={{ marginRight: '5px' }}>
|
||||||
<div className={this.props.classes.button} style={{borderRadius: '50%', cursor: 'pointer', display: 'table-cell',
|
<div className={this.props.classes.button} style={{
|
||||||
verticalAlign: 'middle',
|
borderRadius: '50%', cursor: 'pointer', display: 'table-cell',
|
||||||
textAlign: 'center'}}>
|
verticalAlign: 'middle',
|
||||||
<FontAwesomeIcon icon={faUpload} style={{width: '18px', height: '18px'}}/>
|
textAlign: 'center'
|
||||||
|
}}>
|
||||||
|
<FontAwesomeIcon icon={faUpload} style={{ width: '18px', height: '18px' }} />
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<Tooltip title='Screenshot erstellen' arrow style={{marginRight: '5px'}}>
|
<Tooltip title='Screenshot erstellen' arrow style={{ marginRight: '5px' }}>
|
||||||
<IconButton
|
<IconButton
|
||||||
className={this.props.classes.button}
|
className={this.props.classes.button}
|
||||||
onClick={() => {this.createFileName('svg');}}
|
onClick={() => { this.createFileName('svg'); }}
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon icon={faCamera} size="xs" />
|
<FontAwesomeIcon icon={faCamera} size="xs" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
@ -248,24 +302,55 @@ class WorkspaceFunc extends Component {
|
|||||||
className={this.props.classes.button}
|
className={this.props.classes.button}
|
||||||
onClick={() => this.resetWorkspace()}
|
onClick={() => this.resetWorkspace()}
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon icon={faShare} size="xs" flip='horizontal'/>
|
<FontAwesomeIcon icon={faShare} size="xs" flip='horizontal' />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
<Tooltip title='Blöcke teilen' arrow>
|
||||||
|
<IconButton
|
||||||
|
className={this.props.classes.button}
|
||||||
|
onClick={() => this.shareBlocks()}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faShareAlt} size="xs" flip='horizontal' />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
|
||||||
|
<Dialog open={this.state.share} onClose={this.toggleDialog} aria-labelledby="form-dialog-title">
|
||||||
|
<DialogTitle id="form-dialog-title">Dein Link wurde erstellt.</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
<DialogContentText>
|
||||||
|
Über den folgenden Link kannst du dein Programm teilen.
|
||||||
|
</DialogContentText>
|
||||||
|
<TextField
|
||||||
|
autoFocus
|
||||||
|
margin="dense"
|
||||||
|
id="name"
|
||||||
|
defaultValue={"http://localhost:3000/share/" + this.state.id}
|
||||||
|
label="url"
|
||||||
|
type="email"
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={this.toggleDialog} color="primary">
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
|
||||||
<Dialog
|
<Dialog
|
||||||
open={this.state.open}
|
open={this.state.open}
|
||||||
title={this.state.title}
|
title={this.state.title}
|
||||||
content={this.state.content}
|
content={this.state.content}
|
||||||
onClose={this.toggleDialog}
|
onClose={this.toggleDialog}
|
||||||
onClick={this.state.file ? () => {this.toggleDialog(); this.setState({name: this.props.name})} : this.toggleDialog}
|
onClick={this.state.file ? () => { this.toggleDialog(); this.setState({ name: this.props.name }) } : this.toggleDialog}
|
||||||
button={this.state.file ? 'Abbrechen' : 'Schließen'}
|
button={this.state.file ? 'Abbrechen' : 'Schließen'}
|
||||||
>
|
>
|
||||||
{this.state.file ?
|
{this.state.file ?
|
||||||
<div style={{marginTop: '10px'}}>
|
<div style={{ marginTop: '10px' }}>
|
||||||
<TextField autoFocus placeholder={this.state.saveXml ?'Dateiname' : 'Projektname'} value={this.state.name} onChange={this.setFileName} style={{marginRight: '10px'}}/>
|
<TextField autoFocus placeholder={this.state.saveXml ? 'Dateiname' : 'Projektname'} value={this.state.name} onChange={this.setFileName} style={{ marginRight: '10px' }} />
|
||||||
<Button disabled={!this.state.name} variant='contained' color='primary' onClick={() => {this.state.saveFile ? this.state.file === 'xml' ? this.saveXmlFile() : this.getSvg() : this.renameWorkspace(); this.toggleDialog();}}>Eingabe</Button>
|
<Button disabled={!this.state.name} variant='contained' color='primary' onClick={() => { this.state.saveFile ? this.state.file === 'xml' ? this.saveXmlFile() : this.getSvg() : this.renameWorkspace(); this.toggleDialog(); }}>Eingabe</Button>
|
||||||
</div>
|
</div>
|
||||||
: null}
|
: null}
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
||||||
<Snackbar
|
<Snackbar
|
||||||
@ -295,4 +380,4 @@ const mapStateToProps = state => ({
|
|||||||
name: state.workspace.name
|
name: state.workspace.name
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps, { clearStats, onChangeCode, workspaceName })(withStyles(styles, {withTheme: true})(withWidth()(WorkspaceFunc)));
|
export default connect(mapStateToProps, { clearStats, onChangeCode, workspaceName })(withStyles(styles, { withTheme: true })(withWidth()(WorkspaceFunc)));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user