cleanup code and update some packages
This commit is contained in:
parent
557d66d7d6
commit
b44d858fe6
17557
package-lock.json
generated
17557
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
35
package.json
35
package.json
@ -3,12 +3,12 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@blockly/block-plus-minus": "^2.0.39",
|
"@blockly/block-plus-minus": "^3.0.5",
|
||||||
"@blockly/field-slider": "^2.1.30",
|
"@blockly/field-slider": "^3.0.5",
|
||||||
"@blockly/plugin-scroll-options": "^1.0.4",
|
"@blockly/plugin-scroll-options": "^2.0.5",
|
||||||
"@blockly/plugin-typed-variable-modal": "^3.1.29",
|
"@blockly/plugin-typed-variable-modal": "^4.0.5",
|
||||||
"@blockly/workspace-backpack": "^1.0.12",
|
"@blockly/workspace-backpack": "^1.0.14",
|
||||||
"@blockly/zoom-to-fit": "^2.0.9",
|
"@blockly/zoom-to-fit": "^2.0.14",
|
||||||
"@fortawesome/fontawesome-svg-core": "^1.2.30",
|
"@fortawesome/fontawesome-svg-core": "^1.2.30",
|
||||||
"@fortawesome/free-solid-svg-icons": "^5.14.0",
|
"@fortawesome/free-solid-svg-icons": "^5.14.0",
|
||||||
"@fortawesome/react-fontawesome": "^0.1.11",
|
"@fortawesome/react-fontawesome": "^0.1.11",
|
||||||
@ -26,18 +26,23 @@
|
|||||||
"moment": "^2.28.0",
|
"moment": "^2.28.0",
|
||||||
"prismjs": "^1.25.0",
|
"prismjs": "^1.25.0",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-cookie-consent": "^5.2.0",
|
"react-cookie-consent": "^7.2.1",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"react-markdown": "^5.0.2",
|
"react-markdown": "^5.0.2",
|
||||||
"react-mde": "^11.5.0",
|
"react-mde": "^11.5.0",
|
||||||
"react-redux": "^7.2.4",
|
"react-redux": "^7.2.4",
|
||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^5.2.0",
|
||||||
"react-scripts": "^4.0.3",
|
"react-scripts": "^4.0.3",
|
||||||
"reactour": "^1.18.0",
|
"reactour": "^1.18.7",
|
||||||
"redux": "^4.0.5",
|
"redux": "^4.0.5",
|
||||||
"redux-thunk": "^2.3.0",
|
"redux-thunk": "^2.3.0",
|
||||||
"styled-components": "^4.4.1",
|
"styled-components": "^4.4.1",
|
||||||
"uuid": "^8.3.1"
|
"uuid": "^8.3.1",
|
||||||
|
"watchpack": "^2.3.1"
|
||||||
|
},
|
||||||
|
"resolutions": {
|
||||||
|
"//": "See https://github.com/facebook/create-react-app/issues/11773",
|
||||||
|
"react-error-overlay": "6.0.9"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"start": "react-scripts start",
|
||||||
@ -49,11 +54,9 @@
|
|||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"extends": "react-app"
|
"extends": "react-app"
|
||||||
},
|
},
|
||||||
"browserslist":
|
"browserslist": [
|
||||||
[
|
">0.2%",
|
||||||
">0.2%",
|
"not dead",
|
||||||
"not dead",
|
"not op_mini all"
|
||||||
"not op_mini all"
|
]
|
||||||
]
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
31
src/App.js
31
src/App.js
@ -1,35 +1,34 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from "react";
|
||||||
|
|
||||||
import { BrowserRouter as Router } from 'react-router-dom';
|
import { BrowserRouter as Router } from "react-router-dom";
|
||||||
import { createBrowserHistory } from "history";
|
import { createBrowserHistory } from "history";
|
||||||
|
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from "react-redux";
|
||||||
import store from './store';
|
import store from "./store";
|
||||||
import { loadUser } from './actions/authActions';
|
import { loadUser } from "./actions/authActions";
|
||||||
|
|
||||||
import './App.css';
|
import "./App.css";
|
||||||
|
|
||||||
import { ThemeProvider, createMuiTheme } from '@material-ui/core/styles';
|
import { ThemeProvider, createTheme } from "@material-ui/core/styles";
|
||||||
|
|
||||||
import Content from './components/Content';
|
import Content from "./components/Content";
|
||||||
|
|
||||||
const theme = createMuiTheme({
|
const theme = createTheme({
|
||||||
palette: {
|
palette: {
|
||||||
primary: {
|
primary: {
|
||||||
main: '#4EAF47',
|
main: "#4EAF47",
|
||||||
contrastText: '#ffffff'
|
contrastText: "#ffffff",
|
||||||
},
|
},
|
||||||
secondary: {
|
secondary: {
|
||||||
main: '#DDDDDD'
|
main: "#DDDDDD",
|
||||||
},
|
},
|
||||||
button: {
|
button: {
|
||||||
compile: '#e27136'
|
compile: "#e27136",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
class App extends Component {
|
class App extends Component {
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
store.dispatch(loadUser());
|
store.dispatch(loadUser());
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,6 @@ const CodeEditor = (props) => {
|
|||||||
const [time, setTime] = useState(null);
|
const [time, setTime] = useState(null);
|
||||||
const [value, setValue] = useState("");
|
const [value, setValue] = useState("");
|
||||||
const [resetDialog, setResetDialog] = useState(false);
|
const [resetDialog, setResetDialog] = useState(false);
|
||||||
const [blocklyCode, setBlocklyCode] = useState("");
|
|
||||||
const [defaultValue, setDefaultValue] = useState(
|
const [defaultValue, setDefaultValue] = useState(
|
||||||
localStorage.getItem("ArduinoCode")
|
localStorage.getItem("ArduinoCode")
|
||||||
? localStorage.getItem("ArduinoCode")
|
? localStorage.getItem("ArduinoCode")
|
||||||
@ -62,7 +61,6 @@ void loop() {
|
|||||||
setProgress(false);
|
setProgress(false);
|
||||||
const result = data.data.id;
|
const result = data.data.id;
|
||||||
setId(result);
|
setId(result);
|
||||||
console.log(result);
|
|
||||||
const filename = "sketch";
|
const filename = "sketch";
|
||||||
window.open(
|
window.open(
|
||||||
`${process.env.REACT_APP_COMPILER_URL}/download?id=${result}&board=${process.env.REACT_APP_BOARD}&filename=${filename}`,
|
`${process.env.REACT_APP_COMPILER_URL}/download?id=${result}&board=${process.env.REACT_APP_BOARD}&filename=${filename}`,
|
||||||
@ -134,14 +132,6 @@ void loop() {
|
|||||||
setTimeout(() => setAutoSave(false), 1000);
|
setTimeout(() => setAutoSave(false), 1000);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClose = (event, reason) => {
|
|
||||||
if (reason === "clickaway") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setOpen(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const getBlocklyCode = () => {
|
const getBlocklyCode = () => {
|
||||||
var code = store.getState().workspace.code.arduino;
|
var code = store.getState().workspace.code.arduino;
|
||||||
editorRef.current.setValue(code);
|
editorRef.current.setValue(code);
|
||||||
|
@ -190,7 +190,7 @@ class Compile extends Component {
|
|||||||
className={`compileBlocks ${this.props.classes.iconButton}`}
|
className={`compileBlocks ${this.props.classes.iconButton}`}
|
||||||
onClick={() => this.compile()}
|
onClick={() => this.compile()}
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon icon={faClipboardCheck} size="l" />
|
<FontAwesomeIcon icon={faClipboardCheck} size="m" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
) : (
|
) : (
|
||||||
|
@ -25,19 +25,6 @@ const Sidebar = () => {
|
|||||||
|
|
||||||
const monaco = useMonaco();
|
const monaco = useMonaco();
|
||||||
const loadCode = (code) => {
|
const loadCode = (code) => {
|
||||||
console.log(code);
|
|
||||||
console.log(monaco);
|
|
||||||
const defaultCode = `
|
|
||||||
void setup () {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop(){
|
|
||||||
|
|
||||||
}`;
|
|
||||||
var currentCode = monaco.editor.getModels()[0].getValue();
|
|
||||||
|
|
||||||
setAlert(true);
|
|
||||||
monaco.editor.getModels()[0].setValue(code);
|
monaco.editor.getModels()[0].setValue(code);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ import { Card } from "@material-ui/core";
|
|||||||
import * as Blockly from "blockly";
|
import * as Blockly from "blockly";
|
||||||
import { default as MonacoEditor } from "@monaco-editor/react";
|
import { default as MonacoEditor } from "@monaco-editor/react";
|
||||||
|
|
||||||
|
|
||||||
const Accordion = withStyles((theme) => ({
|
const Accordion = withStyles((theme) => ({
|
||||||
root: {
|
root: {
|
||||||
border: `1px solid ${theme.palette.secondary.main}`,
|
border: `1px solid ${theme.palette.secondary.main}`,
|
||||||
@ -134,7 +133,7 @@ class CodeViewer extends Component {
|
|||||||
options={{
|
options={{
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
|
|
||||||
fontSize: "12px",
|
fontSize: "16px",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</AccordionDetails>
|
</AccordionDetails>
|
||||||
|
@ -54,12 +54,17 @@ class Home extends Component {
|
|||||||
key: "",
|
key: "",
|
||||||
message: "",
|
message: "",
|
||||||
open: true,
|
open: true,
|
||||||
|
resumeWork: false,
|
||||||
initialXml: localStorage.getItem("autoSaveXML"),
|
initialXml: localStorage.getItem("autoSaveXML"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
console.log(this.props.platform);
|
if (this.state.initialXml) {
|
||||||
|
this.setState({ resumeWork: true });
|
||||||
|
} else {
|
||||||
|
console.log("new work");
|
||||||
|
}
|
||||||
if (this.props.platform === true) {
|
if (this.props.platform === true) {
|
||||||
this.setState({ codeOn: false });
|
this.setState({ codeOn: false });
|
||||||
}
|
}
|
||||||
@ -95,6 +100,10 @@ class Home extends Component {
|
|||||||
this.setState({ open: !this.state });
|
this.setState({ open: !this.state });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
toogleResumeWork = () => {
|
||||||
|
this.setState({ resumeWork: !this.state.resumeWork });
|
||||||
|
};
|
||||||
|
|
||||||
onChangeCheckbox = (e) => {
|
onChangeCheckbox = (e) => {
|
||||||
if (e.target.checked) {
|
if (e.target.checked) {
|
||||||
window.localStorage.setItem("ota", e.target.checked);
|
window.localStorage.setItem("ota", e.target.checked);
|
||||||
@ -188,6 +197,25 @@ class Home extends Component {
|
|||||||
) : null}
|
) : null}
|
||||||
</Grid>
|
</Grid>
|
||||||
<HintTutorialExists />
|
<HintTutorialExists />
|
||||||
|
<Dialog
|
||||||
|
style={{ zIndex: 9999999 }}
|
||||||
|
fullWidth
|
||||||
|
maxWidth={"sm"}
|
||||||
|
open={this.state.resumeWork}
|
||||||
|
title={Blockly.Msg.tabletDialog_headline}
|
||||||
|
content={""}
|
||||||
|
onClose={this.toogleResumeWork}
|
||||||
|
onClick={this.toogleResumeWork}
|
||||||
|
button={Blockly.Msg.button_close}
|
||||||
|
>
|
||||||
|
<div>{Blockly.Msg.tabletDialog_text}</div>
|
||||||
|
<div>
|
||||||
|
{Blockly.Msg.tabletDialog_more}{" "}
|
||||||
|
<a href="https://sensebox.de/app" target="_blank" rel="noreferrer">
|
||||||
|
https://sensebox.de/app
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</Dialog>
|
||||||
{this.props.platform ? (
|
{this.props.platform ? (
|
||||||
<Dialog
|
<Dialog
|
||||||
style={{ zIndex: 9999999 }}
|
style={{ zIndex: 9999999 }}
|
||||||
@ -223,7 +251,7 @@ Home.propTypes = {
|
|||||||
workspaceName: PropTypes.func.isRequired,
|
workspaceName: PropTypes.func.isRequired,
|
||||||
message: PropTypes.object.isRequired,
|
message: PropTypes.object.isRequired,
|
||||||
statistics: PropTypes.bool.isRequired,
|
statistics: PropTypes.bool.isRequired,
|
||||||
platform: PropTypes.object.isRequired,
|
platform: PropTypes.bool.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = (state) => ({
|
const mapStateToProps = (state) => ({
|
||||||
|
@ -359,9 +359,9 @@ class Navbar extends Component {
|
|||||||
Navbar.propTypes = {
|
Navbar.propTypes = {
|
||||||
tutorialIsLoading: PropTypes.bool.isRequired,
|
tutorialIsLoading: PropTypes.bool.isRequired,
|
||||||
projectIsLoading: PropTypes.bool.isRequired,
|
projectIsLoading: PropTypes.bool.isRequired,
|
||||||
isAuthenticated: PropTypes.bool.isRequired,
|
isAuthenticated: PropTypes.bool,
|
||||||
user: PropTypes.object,
|
user: PropTypes.object,
|
||||||
tutorial: PropTypes.object.isRequired,
|
tutorial: PropTypes.object,
|
||||||
activeStep: PropTypes.number.isRequired,
|
activeStep: PropTypes.number.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ class Routes extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Home.propTypes = {
|
Home.propTypes = {
|
||||||
visitPage: PropTypes.func.isRequired,
|
visitPage: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(null, { visitPage })(withRouter(Routes));
|
export default connect(null, { visitPage })(withRouter(Routes));
|
||||||
|
@ -1,53 +1,57 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from "react";
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from "prop-types";
|
||||||
import { connect } from 'react-redux';
|
import { connect } from "react-redux";
|
||||||
import { changeContent, deleteProperty, setError, deleteError } from '../../../actions/tutorialBuilderActions';
|
import {
|
||||||
|
changeContent,
|
||||||
|
deleteProperty,
|
||||||
|
setError,
|
||||||
|
deleteError,
|
||||||
|
} from "../../../actions/tutorialBuilderActions";
|
||||||
|
|
||||||
import moment from 'moment';
|
import moment from "moment";
|
||||||
import localization from 'moment/locale/de';
|
import localization from "moment/locale/de";
|
||||||
import * as Blockly from 'blockly/core';
|
import * as Blockly from "blockly/core";
|
||||||
|
|
||||||
import { initialXml } from '../../Blockly//initialXml.js';
|
import { initialXml } from "../../Blockly//initialXml.js";
|
||||||
import BlocklyWindow from '../../Blockly/BlocklyWindow';
|
import BlocklyWindow from "../../Blockly/BlocklyWindow";
|
||||||
|
|
||||||
import { withStyles } from '@material-ui/core/styles';
|
import { withStyles } from "@material-ui/core/styles";
|
||||||
import Switch from '@material-ui/core/Switch';
|
import Switch from "@material-ui/core/Switch";
|
||||||
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
import FormControlLabel from "@material-ui/core/FormControlLabel";
|
||||||
import FormHelperText from '@material-ui/core/FormHelperText';
|
import FormHelperText from "@material-ui/core/FormHelperText";
|
||||||
import FormLabel from '@material-ui/core/FormLabel';
|
import FormLabel from "@material-ui/core/FormLabel";
|
||||||
import Button from '@material-ui/core/Button';
|
import Button from "@material-ui/core/Button";
|
||||||
import Grid from '@material-ui/core/Grid';
|
import Grid from "@material-ui/core/Grid";
|
||||||
|
|
||||||
const styles = (theme) => ({
|
const styles = (theme) => ({
|
||||||
errorColor: {
|
errorColor: {
|
||||||
color: theme.palette.error.dark
|
color: theme.palette.error.dark,
|
||||||
},
|
},
|
||||||
errorBorder: {
|
errorBorder: {
|
||||||
border: `1px solid ${theme.palette.error.dark}`
|
border: `1px solid ${theme.palette.error.dark}`,
|
||||||
},
|
},
|
||||||
errorButton: {
|
errorButton: {
|
||||||
marginTop: '5px',
|
marginTop: "5px",
|
||||||
height: '40px',
|
height: "40px",
|
||||||
backgroundColor: theme.palette.error.dark,
|
backgroundColor: theme.palette.error.dark,
|
||||||
'&:hover': {
|
"&:hover": {
|
||||||
backgroundColor: theme.palette.error.dark
|
backgroundColor: theme.palette.error.dark,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
class BlocklyExample extends Component {
|
class BlocklyExample extends Component {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
checked: props.task ? props.task : props.value ? true : false,
|
checked: props.task ? props.task : props.value ? true : false,
|
||||||
input: null,
|
input: null,
|
||||||
disabled: false
|
disabled: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
moment.updateLocale('de', localization);
|
moment.updateLocale("de", localization);
|
||||||
this.isError();
|
this.isError();
|
||||||
// if(this.props.task){
|
// if(this.props.task){
|
||||||
// this.props.setError(this.props.index, 'xml');
|
// this.props.setError(this.props.index, 'xml');
|
||||||
@ -56,7 +60,14 @@ class BlocklyExample extends Component {
|
|||||||
|
|
||||||
componentDidUpdate(props, state) {
|
componentDidUpdate(props, state) {
|
||||||
if (props.task !== this.props.task || props.value !== this.props.value) {
|
if (props.task !== this.props.task || props.value !== this.props.value) {
|
||||||
this.setState({ checked: this.props.task ? this.props.task : this.props.value ? true : false },
|
this.setState(
|
||||||
|
{
|
||||||
|
checked: this.props.task
|
||||||
|
? this.props.task
|
||||||
|
: this.props.value
|
||||||
|
? true
|
||||||
|
: false,
|
||||||
|
},
|
||||||
() => this.isError()
|
() => this.isError()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -77,12 +88,11 @@ class BlocklyExample extends Component {
|
|||||||
// check if value is valid xml;
|
// check if value is valid xml;
|
||||||
try {
|
try {
|
||||||
Blockly.Xml.textToDom(xml);
|
Blockly.Xml.textToDom(xml);
|
||||||
this.props.deleteError(this.props.index, 'xml');
|
this.props.deleteError(this.props.index, "xml");
|
||||||
}
|
} catch (err) {
|
||||||
catch (err) {
|
|
||||||
xml = initialXml;
|
xml = initialXml;
|
||||||
// not valid xml, throw error in redux store
|
// not valid xml, throw error in redux store
|
||||||
this.props.setError(this.props.index, 'xml');
|
this.props.setError(this.props.index, "xml");
|
||||||
}
|
}
|
||||||
if (!this.props.task) {
|
if (!this.props.task) {
|
||||||
// instruction can also display only one block, which does not necessarily
|
// instruction can also display only one block, which does not necessarily
|
||||||
@ -90,31 +100,38 @@ class BlocklyExample extends Component {
|
|||||||
xml = xml.replace('deletable="false"', 'deletable="true"');
|
xml = xml.replace('deletable="false"', 'deletable="true"');
|
||||||
}
|
}
|
||||||
this.setState({ xml: xml });
|
this.setState({ xml: xml });
|
||||||
|
} else {
|
||||||
|
this.props.deleteError(this.props.index, "xml");
|
||||||
}
|
}
|
||||||
else {
|
};
|
||||||
this.props.deleteError(this.props.index, 'xml');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onChange = (value) => {
|
onChange = (value) => {
|
||||||
var oldValue = this.state.checked;
|
var oldValue = this.state.checked;
|
||||||
this.setState({ checked: value });
|
this.setState({ checked: value });
|
||||||
if (oldValue !== value && !value) {
|
if (oldValue !== value && !value) {
|
||||||
this.props.deleteError(this.props.index, 'xml');
|
this.props.deleteError(this.props.index, "xml");
|
||||||
this.props.deleteProperty(this.props.index, 'xml');
|
this.props.deleteProperty(this.props.index, "xml");
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
setXml = () => {
|
setXml = () => {
|
||||||
var xml = this.props.xml;
|
var xml = this.props.xml;
|
||||||
this.props.changeContent(xml, this.props.index, 'xml');
|
this.props.changeContent(xml, this.props.index, "xml");
|
||||||
this.setState({ input: moment(Date.now()).format('LTS') });
|
this.setState({ input: moment(Date.now()).format("LTS") });
|
||||||
}
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div style={{ marginBottom: '10px', padding: '18.5px 14px', borderRadius: '25px', border: '1px solid lightgrey', width: 'calc(100% - 28px)' }}>
|
<div
|
||||||
{!this.props.task ?
|
style={{
|
||||||
|
marginBottom: "10px",
|
||||||
|
padding: "18.5px 14px",
|
||||||
|
borderRadius: "25px",
|
||||||
|
border: "1px solid lightgrey",
|
||||||
|
width: "calc(100% - 28px)",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{!this.props.task ? (
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
labelPlacement="end"
|
labelPlacement="end"
|
||||||
label={"Blockly Beispiel"}
|
label={"Blockly Beispiel"}
|
||||||
@ -126,45 +143,77 @@ class BlocklyExample extends Component {
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
: <FormLabel style={{ color: 'black' }}>{Blockly.Msg.builder_solution}</FormLabel>}
|
) : (
|
||||||
{this.state.checked ? !this.props.value || this.props.error ?
|
<FormLabel style={{ color: "black" }}>
|
||||||
<FormHelperText style={{ lineHeight: 'initial' }} className={this.props.classes.errorColor}>{`Reiche deine Blöcke ein, indem du auf den '${this.props.task ? Blockly.Msg.builder_solution_submit : Blockly.Msg.builder_example_submit}'-Button klickst.`}</FormHelperText>
|
{Blockly.Msg.builder_solution}
|
||||||
: this.state.input ? <FormHelperText style={{ lineHeight: 'initial' }}>Die letzte Einreichung erfolgte um {this.state.input} Uhr.</FormHelperText> : null
|
</FormLabel>
|
||||||
: null}
|
)}
|
||||||
{this.state.checked && !this.props.task ?
|
{this.state.checked ? (
|
||||||
<FormHelperText style={{ lineHeight: 'initial' }}>{Blockly.Msg.builder_comment}</FormHelperText>
|
!this.props.value || this.props.error ? (
|
||||||
: null}
|
<FormHelperText
|
||||||
|
style={{ lineHeight: "initial" }}
|
||||||
|
className={this.props.classes.errorColor}
|
||||||
|
>{`Reiche deine Blöcke ein, indem du auf den '${
|
||||||
|
this.props.task
|
||||||
|
? Blockly.Msg.builder_solution_submit
|
||||||
|
: Blockly.Msg.builder_example_submit
|
||||||
|
}'-Button klickst.`}</FormHelperText>
|
||||||
|
) : this.state.input ? (
|
||||||
|
<FormHelperText style={{ lineHeight: "initial" }}>
|
||||||
|
Die letzte Einreichung erfolgte um {this.state.input} Uhr.
|
||||||
|
</FormHelperText>
|
||||||
|
) : null
|
||||||
|
) : null}
|
||||||
|
{this.state.checked && !this.props.task ? (
|
||||||
|
<FormHelperText style={{ lineHeight: "initial" }}>
|
||||||
|
{Blockly.Msg.builder_comment}
|
||||||
|
</FormHelperText>
|
||||||
|
) : null}
|
||||||
{/* ensure that the correct xml-file is displayed in the workspace */}
|
{/* ensure that the correct xml-file is displayed in the workspace */}
|
||||||
{this.state.checked && this.state.xml ? (() => {
|
{this.state.checked && this.state.xml
|
||||||
return (
|
? (() => {
|
||||||
<div style={{ marginTop: '10px' }}>
|
return (
|
||||||
<Grid container className={!this.props.value || this.props.error ? this.props.classes.errorBorder : null}>
|
<div style={{ marginTop: "10px" }}>
|
||||||
<Grid item xs={12}>
|
<Grid
|
||||||
<BlocklyWindow
|
container
|
||||||
blockDisabled={this.props.task}
|
className={
|
||||||
trashcan={false}
|
!this.props.value || this.props.error
|
||||||
initialXml={this.state.xml}
|
? this.props.classes.errorBorder
|
||||||
blocklyCSS={{ height: '500px' }}
|
: null
|
||||||
/>
|
}
|
||||||
</Grid>
|
>
|
||||||
</Grid>
|
<Grid item xs={12}>
|
||||||
<Button
|
<BlocklyWindow
|
||||||
className={!this.props.value || this.props.error ? this.props.classes.errorButton : null}
|
blockDisabled={this.props.task}
|
||||||
style={{ marginTop: '5px', height: '40px' }}
|
trashcan={false}
|
||||||
variant='contained'
|
initialXml={this.state.xml}
|
||||||
color='primary'
|
blocklyCSS={{ height: "500px" }}
|
||||||
disabled={this.state.disabled}
|
/>
|
||||||
onClick={() => this.setXml()}
|
</Grid>
|
||||||
>
|
</Grid>
|
||||||
{this.props.task ? Blockly.Msg.builder_solution_submit : Blockly.Msg.builder_example_submit}
|
<Button
|
||||||
</Button>
|
className={
|
||||||
</div>
|
!this.props.value || this.props.error
|
||||||
)
|
? this.props.classes.errorButton
|
||||||
})()
|
: null
|
||||||
|
}
|
||||||
|
style={{ marginTop: "5px", height: "40px" }}
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
disabled={this.state.disabled}
|
||||||
|
onClick={() => this.setXml()}
|
||||||
|
>
|
||||||
|
{this.props.task
|
||||||
|
? Blockly.Msg.builder_solution_submit
|
||||||
|
: Blockly.Msg.builder_example_submit}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})()
|
||||||
: null}
|
: null}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BlocklyExample.propTypes = {
|
BlocklyExample.propTypes = {
|
||||||
@ -172,12 +221,16 @@ BlocklyExample.propTypes = {
|
|||||||
deleteProperty: PropTypes.func.isRequired,
|
deleteProperty: PropTypes.func.isRequired,
|
||||||
setError: PropTypes.func.isRequired,
|
setError: PropTypes.func.isRequired,
|
||||||
deleteError: PropTypes.func.isRequired,
|
deleteError: PropTypes.func.isRequired,
|
||||||
xml: PropTypes.string.isRequired
|
xml: PropTypes.string.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = (state) => ({
|
||||||
xml: state.workspace.code.xml
|
xml: state.workspace.code.xml,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, {
|
||||||
export default connect(mapStateToProps, { changeContent, deleteProperty, setError, deleteError })(withStyles(styles, { withTheme: true })(BlocklyExample));
|
changeContent,
|
||||||
|
deleteProperty,
|
||||||
|
setError,
|
||||||
|
deleteError,
|
||||||
|
})(withStyles(styles, { withTheme: true })(BlocklyExample));
|
||||||
|
@ -1,75 +1,79 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from "react";
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from "prop-types";
|
||||||
import { connect } from 'react-redux';
|
import { connect } from "react-redux";
|
||||||
import Dialog from '../Dialog';
|
import Dialog from "../Dialog";
|
||||||
|
|
||||||
import { withStyles } from '@material-ui/core/styles';
|
import { withStyles } from "@material-ui/core/styles";
|
||||||
import Checkbox from '@material-ui/core/Checkbox';
|
import Checkbox from "@material-ui/core/Checkbox";
|
||||||
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
import FormControlLabel from "@material-ui/core/FormControlLabel";
|
||||||
import * as Blockly from 'blockly'
|
import * as Blockly from "blockly";
|
||||||
import ReactMarkdown from 'react-markdown';
|
import ReactMarkdown from "react-markdown";
|
||||||
|
|
||||||
const styles = (theme) => ({
|
const styles = (theme) => ({
|
||||||
link: {
|
link: {
|
||||||
color: theme.palette.primary.main,
|
color: theme.palette.primary.main,
|
||||||
textDecoration: 'none',
|
textDecoration: "none",
|
||||||
'&:hover': {
|
"&:hover": {
|
||||||
color: theme.palette.primary.main,
|
color: theme.palette.primary.main,
|
||||||
textDecoration: `underline`
|
textDecoration: `underline`,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
label: {
|
label: {
|
||||||
fontSize: '0.9rem',
|
fontSize: "0.9rem",
|
||||||
color: 'grey'
|
color: "grey",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
class HintTutorialExists extends Component {
|
class HintTutorialExists extends Component {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
var previousPageWasAnotherDomain = props.pageVisits === 0;
|
var previousPageWasAnotherDomain = props.pageVisits === 0;
|
||||||
var userDoNotWantToSeeNews = window.localStorage.getItem('news') ? true : false;
|
var userDoNotWantToSeeNews = window.localStorage.getItem("news")
|
||||||
|
? true
|
||||||
|
: false;
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
open: userDoNotWantToSeeNews ? !userDoNotWantToSeeNews : previousPageWasAnotherDomain
|
open: userDoNotWantToSeeNews
|
||||||
|
? !userDoNotWantToSeeNews
|
||||||
|
: previousPageWasAnotherDomain,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleDialog = () => {
|
toggleDialog = () => {
|
||||||
this.setState({ open: !this.state });
|
this.setState({ open: !this.state });
|
||||||
}
|
};
|
||||||
|
|
||||||
onChange = (e) => {
|
onChange = (e) => {
|
||||||
if (e.target.checked) {
|
if (e.target.checked) {
|
||||||
window.localStorage.setItem('news', e.target.checked);
|
window.localStorage.setItem("news", e.target.checked);
|
||||||
|
} else {
|
||||||
|
window.localStorage.removeItem("news");
|
||||||
}
|
}
|
||||||
else {
|
};
|
||||||
window.localStorage.removeItem('news');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
style={{ zIndex: 9999999 }}
|
style={{ zIndex: 9999999 }}
|
||||||
fullWidth
|
fullWidth
|
||||||
maxWidth={'sm'}
|
maxWidth={"sm"}
|
||||||
open={this.state.open}
|
open={this.state.open}
|
||||||
title={Blockly.Msg.messages_newblockly_head}
|
title={Blockly.Msg.messages_newblockly_head}
|
||||||
content={''}
|
content={""}
|
||||||
onClose={this.toggleDialog}
|
onClose={this.toggleDialog}
|
||||||
onClick={this.toggleDialog}
|
onClick={this.toggleDialog}
|
||||||
button={Blockly.Msg.button_close}
|
button={Blockly.Msg.button_close}
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<ReactMarkdown linkTarget="_blank">{Blockly.Msg.messages_newblockly_text}</ReactMarkdown>
|
<ReactMarkdown linkTarget="_blank">
|
||||||
|
{Blockly.Msg.messages_newblockly_text}
|
||||||
|
</ReactMarkdown>
|
||||||
</div>
|
</div>
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
style={{ marginTop: '20px' }}
|
style={{ marginTop: "20px" }}
|
||||||
classes={{ label: this.props.classes.label }}
|
classes={{ label: this.props.classes.label }}
|
||||||
control={
|
control={
|
||||||
<Checkbox
|
<Checkbox
|
||||||
size={'small'}
|
size={"small"}
|
||||||
value={true}
|
value={true}
|
||||||
checked={this.state.checked}
|
checked={this.state.checked}
|
||||||
onChange={(e) => this.onChange(e)}
|
onChange={(e) => this.onChange(e)}
|
||||||
@ -81,15 +85,18 @@ class HintTutorialExists extends Component {
|
|||||||
/>
|
/>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HintTutorialExists.propTypes = {
|
HintTutorialExists.propTypes = {
|
||||||
pageVisits: PropTypes.number.isRequired
|
pageVisits: PropTypes.number.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = (state) => ({
|
||||||
pageVisits: state.general.pageVisits
|
pageVisits: state.general.pageVisits,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps, null)(withStyles(styles, { withTheme: true })(HintTutorialExists));
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
null
|
||||||
|
)(withStyles(styles, { withTheme: true })(HintTutorialExists));
|
||||||
|
@ -1,51 +1,49 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from "react";
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from "prop-types";
|
||||||
import { connect } from 'react-redux';
|
import { connect } from "react-redux";
|
||||||
import { tutorialCheck, tutorialStep } from '../../actions/tutorialActions';
|
import { tutorialCheck, tutorialStep } from "../../actions/tutorialActions";
|
||||||
|
|
||||||
import { withRouter } from 'react-router-dom';
|
import { withRouter } from "react-router-dom";
|
||||||
|
|
||||||
import Compile from '../Workspace/Compile';
|
import Compile from "../Workspace/Compile";
|
||||||
import Dialog from '../Dialog';
|
import Dialog from "../Dialog";
|
||||||
|
|
||||||
import { checkXml } from '../../helpers/compareXml';
|
import { checkXml } from "../../helpers/compareXml";
|
||||||
|
|
||||||
import { withStyles } from '@material-ui/core/styles';
|
import { withStyles } from "@material-ui/core/styles";
|
||||||
import IconButton from '@material-ui/core/IconButton';
|
import IconButton from "@material-ui/core/IconButton";
|
||||||
import Tooltip from '@material-ui/core/Tooltip';
|
import Tooltip from "@material-ui/core/Tooltip";
|
||||||
import Button from '@material-ui/core/Button';
|
import Button from "@material-ui/core/Button";
|
||||||
|
|
||||||
import { faClipboardCheck } from "@fortawesome/free-solid-svg-icons";
|
import { faClipboardCheck } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
|
|
||||||
import * as Blockly from 'blockly'
|
import * as Blockly from "blockly";
|
||||||
|
|
||||||
const styles = (theme) => ({
|
const styles = (theme) => ({
|
||||||
compile: {
|
compile: {
|
||||||
backgroundColor: theme.palette.button.compile,
|
backgroundColor: theme.palette.button.compile,
|
||||||
color: theme.palette.primary.contrastText,
|
color: theme.palette.primary.contrastText,
|
||||||
'&:hover': {
|
"&:hover": {
|
||||||
backgroundColor: theme.palette.button.compile,
|
backgroundColor: theme.palette.button.compile,
|
||||||
color: theme.palette.primary.contrastText,
|
color: theme.palette.primary.contrastText,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
class SolutionCheck extends Component {
|
class SolutionCheck extends Component {
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
open: false,
|
open: false,
|
||||||
msg: ''
|
msg: "",
|
||||||
}
|
};
|
||||||
|
|
||||||
toggleDialog = () => {
|
toggleDialog = () => {
|
||||||
if (this.state.open) {
|
if (this.state.open) {
|
||||||
this.setState({ open: false, msg: '' });
|
this.setState({ open: false, msg: "" });
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
this.setState({ open: !this.state });
|
this.setState({ open: !this.state });
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
check = () => {
|
check = () => {
|
||||||
const tutorial = this.props.tutorial;
|
const tutorial = this.props.tutorial;
|
||||||
@ -53,7 +51,7 @@ class SolutionCheck extends Component {
|
|||||||
var msg = checkXml(step.xml, this.props.xml);
|
var msg = checkXml(step.xml, this.props.xml);
|
||||||
this.props.tutorialCheck(msg.type, step);
|
this.props.tutorialCheck(msg.type, step);
|
||||||
this.setState({ msg, open: true });
|
this.setState({ msg, open: true });
|
||||||
}
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const steps = this.props.tutorial.steps;
|
const steps = this.props.tutorial.steps;
|
||||||
@ -62,68 +60,74 @@ class SolutionCheck extends Component {
|
|||||||
<Tooltip title={Blockly.Msg.tooltip_check_solution} arrow>
|
<Tooltip title={Blockly.Msg.tooltip_check_solution} arrow>
|
||||||
<IconButton
|
<IconButton
|
||||||
className={`solutionCheck ${this.props.classes.compile}`}
|
className={`solutionCheck ${this.props.classes.compile}`}
|
||||||
style={{ width: '40px', height: '40px', marginRight: '5px' }}
|
style={{ width: "40px", height: "40px", marginRight: "5px" }}
|
||||||
onClick={() => this.check()}
|
onClick={() => this.check()}
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon icon={faClipboardCheck} size="l" />
|
<FontAwesomeIcon icon={faClipboardCheck} size="m" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
<Dialog
|
<Dialog
|
||||||
style={{ zIndex: 9999999 }}
|
style={{ zIndex: 9999999 }}
|
||||||
fullWidth
|
fullWidth
|
||||||
maxWidth={'sm'}
|
maxWidth={"sm"}
|
||||||
open={this.state.open}
|
open={this.state.open}
|
||||||
title={this.state.msg.type === 'error' ? 'Fehler' : 'Erfolg'}
|
title={this.state.msg.type === "error" ? "Fehler" : "Erfolg"}
|
||||||
content={this.state.msg.text}
|
content={this.state.msg.text}
|
||||||
onClose={this.toggleDialog}
|
onClose={this.toggleDialog}
|
||||||
onClick={this.toggleDialog}
|
onClick={this.toggleDialog}
|
||||||
button={Blockly.Msg.button_close}
|
button={Blockly.Msg.button_close}
|
||||||
>
|
>
|
||||||
{this.state.msg.type === 'success' ?
|
{this.state.msg.type === "success" ? (
|
||||||
<div style={{ marginTop: '20px', display: 'flex' }}>
|
<div style={{ marginTop: "20px", display: "flex" }}>
|
||||||
<Compile />
|
<Compile />
|
||||||
{this.props.activeStep === steps.length - 1 ?
|
{this.props.activeStep === steps.length - 1 ? (
|
||||||
<Button
|
<Button
|
||||||
style={{ marginLeft: '10px' }}
|
style={{ marginLeft: "10px" }}
|
||||||
variant="contained"
|
variant="contained"
|
||||||
color="primary"
|
color="primary"
|
||||||
onClick={() => { this.toggleDialog(); this.props.history.push(`/tutorial/`) }}
|
onClick={() => {
|
||||||
|
this.toggleDialog();
|
||||||
|
this.props.history.push(`/tutorial/`);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{Blockly.Msg.button_tutorial_overview}
|
{Blockly.Msg.button_tutorial_overview}
|
||||||
</Button>
|
</Button>
|
||||||
:
|
) : (
|
||||||
<Button
|
<Button
|
||||||
style={{ marginLeft: '10px' }}
|
style={{ marginLeft: "10px" }}
|
||||||
variant="contained"
|
variant="contained"
|
||||||
color="primary"
|
color="primary"
|
||||||
onClick={() => { this.toggleDialog(); this.props.tutorialStep(this.props.activeStep + 1) }}
|
onClick={() => {
|
||||||
|
this.toggleDialog();
|
||||||
|
this.props.tutorialStep(this.props.activeStep + 1);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{Blockly.Msg.button_next}
|
{Blockly.Msg.button_next}
|
||||||
</Button>
|
</Button>
|
||||||
}
|
)}
|
||||||
</div>
|
</div>
|
||||||
: null}
|
) : null}
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SolutionCheck.propTypes = {
|
SolutionCheck.propTypes = {
|
||||||
tutorialCheck: PropTypes.func.isRequired,
|
tutorialCheck: PropTypes.func.isRequired,
|
||||||
tutorialStep: PropTypes.func.isRequired,
|
tutorialStep: PropTypes.func.isRequired,
|
||||||
activeStep: PropTypes.number.isRequired,
|
activeStep: PropTypes.number.isRequired,
|
||||||
xml: PropTypes.string.isRequired,
|
xml: PropTypes.string.isRequired,
|
||||||
tutorial: PropTypes.object.isRequired
|
tutorial: PropTypes.object.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = (state) => ({
|
||||||
activeStep: state.tutorial.activeStep,
|
activeStep: state.tutorial.activeStep,
|
||||||
xml: state.workspace.code.xml,
|
xml: state.workspace.code.xml,
|
||||||
tutorial: state.tutorial.tutorials[0]
|
tutorial: state.tutorial.tutorials[0],
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps, { tutorialCheck, tutorialStep })(withStyles(styles, { withTheme: true })(withRouter(SolutionCheck)));
|
export default connect(mapStateToProps, { tutorialCheck, tutorialStep })(
|
||||||
|
withStyles(styles, { withTheme: true })(withRouter(SolutionCheck))
|
||||||
|
);
|
||||||
|
@ -190,7 +190,7 @@ class Compile extends Component {
|
|||||||
className={`compileBlocks ${this.props.classes.iconButton}`}
|
className={`compileBlocks ${this.props.classes.iconButton}`}
|
||||||
onClick={() => this.compile()}
|
onClick={() => this.compile()}
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon icon={faClipboardCheck} size="l" />
|
<FontAwesomeIcon icon={faClipboardCheck} size="m" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
) : (
|
) : (
|
||||||
|
@ -1,99 +1,110 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from "react";
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from "prop-types";
|
||||||
import { connect } from 'react-redux';
|
import { connect } from "react-redux";
|
||||||
import { workspaceName } from '../../actions/workspaceActions';
|
import { workspaceName } from "../../actions/workspaceActions";
|
||||||
|
|
||||||
import { withStyles } from '@material-ui/core/styles';
|
import { withStyles } from "@material-ui/core/styles";
|
||||||
import Button from '@material-ui/core/Button';
|
import Button from "@material-ui/core/Button";
|
||||||
import IconButton from '@material-ui/core/IconButton';
|
import IconButton from "@material-ui/core/IconButton";
|
||||||
import Tooltip from '@material-ui/core/Tooltip';
|
import Tooltip from "@material-ui/core/Tooltip";
|
||||||
|
|
||||||
import { faCopy } from "@fortawesome/free-solid-svg-icons";
|
import { faCopy } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import * as Blockly from 'blockly/core';
|
import * as Blockly from "blockly/core";
|
||||||
import Snackbar from '../Snackbar';
|
import Snackbar from "../Snackbar";
|
||||||
|
|
||||||
|
|
||||||
const styles = (theme) => ({
|
const styles = (theme) => ({
|
||||||
backdrop: {
|
backdrop: {
|
||||||
zIndex: theme.zIndex.drawer + 1,
|
zIndex: theme.zIndex.drawer + 1,
|
||||||
color: '#fff',
|
color: "#fff",
|
||||||
|
},
|
||||||
|
iconButton: {
|
||||||
|
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,
|
||||||
},
|
},
|
||||||
iconButton: {
|
},
|
||||||
backgroundColor: theme.palette.primary.main,
|
button: {
|
||||||
color: theme.palette.primary.contrastText,
|
backgroundColor: theme.palette.button.copycode,
|
||||||
width: '40px',
|
color: theme.palette.primary.contrastText,
|
||||||
height: '40px',
|
"&:hover": {
|
||||||
'&:hover': {
|
backgroundColor: theme.palette.button.copycode,
|
||||||
backgroundColor: theme.palette.primary.main,
|
color: theme.palette.primary.contrastText,
|
||||||
color: theme.palette.primary.contrastText,
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
button: {
|
},
|
||||||
backgroundColor: theme.palette.button.copycode,
|
|
||||||
color: theme.palette.primary.contrastText,
|
|
||||||
'&:hover': {
|
|
||||||
backgroundColor: theme.palette.button.copycode,
|
|
||||||
color: theme.palette.primary.contrastText,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
class CopyCode extends Component {
|
class CopyCode extends Component {
|
||||||
|
constructor(props) {
|
||||||
constructor(props) {
|
super(props);
|
||||||
super(props);
|
this.state = {
|
||||||
this.state = {
|
snackbar: false,
|
||||||
snackbar: false,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
copyCode = () => {
|
|
||||||
navigator.clipboard.writeText(this.props.arduino)
|
|
||||||
this.setState({ snackbar: true, type: 'success', key: Date.now(), message: Blockly.Msg.messages_copy_code });
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<div style={{}}>
|
|
||||||
{this.props.iconButton ?
|
|
||||||
<Tooltip title={Blockly.Msg.tooltip_copy_code} arrow style={{ marginRight: '5px' }}>
|
|
||||||
<IconButton
|
|
||||||
className={`copyCode ${this.props.classes.iconButton}`}
|
|
||||||
onClick={() => this.copyCode()}
|
|
||||||
>
|
|
||||||
<FontAwesomeIcon icon={faCopy} size="l" />
|
|
||||||
</IconButton>
|
|
||||||
</Tooltip>
|
|
||||||
:
|
|
||||||
<Button style={{ float: 'right', color: 'white' }} variant="contained" className={this.props.classes.button} onClick={() => this.copyCode()}>
|
|
||||||
<FontAwesomeIcon icon={faCopy} style={{ marginRight: '5px' }} /> Code kopieren
|
|
||||||
</Button>
|
|
||||||
}
|
|
||||||
<Snackbar
|
|
||||||
open={this.state.snackbar}
|
|
||||||
message={this.state.message}
|
|
||||||
type={this.state.type}
|
|
||||||
key={this.state.key}
|
|
||||||
/>
|
|
||||||
|
|
||||||
</div >
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
copyCode = () => {
|
||||||
|
navigator.clipboard.writeText(this.props.arduino);
|
||||||
|
this.setState({
|
||||||
|
snackbar: true,
|
||||||
|
type: "success",
|
||||||
|
key: Date.now(),
|
||||||
|
message: Blockly.Msg.messages_copy_code,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div style={{}}>
|
||||||
|
{this.props.iconButton ? (
|
||||||
|
<Tooltip
|
||||||
|
title={Blockly.Msg.tooltip_copy_code}
|
||||||
|
arrow
|
||||||
|
style={{ marginRight: "5px" }}
|
||||||
|
>
|
||||||
|
<IconButton
|
||||||
|
className={`copyCode ${this.props.classes.iconButton}`}
|
||||||
|
onClick={() => this.copyCode()}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faCopy} size="m" />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
) : (
|
||||||
|
<Button
|
||||||
|
style={{ float: "right", color: "white" }}
|
||||||
|
variant="contained"
|
||||||
|
className={this.props.classes.button}
|
||||||
|
onClick={() => this.copyCode()}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faCopy} style={{ marginRight: "5px" }} />{" "}
|
||||||
|
Code kopieren
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
<Snackbar
|
||||||
|
open={this.state.snackbar}
|
||||||
|
message={this.state.message}
|
||||||
|
type={this.state.type}
|
||||||
|
key={this.state.key}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CopyCode.propTypes = {
|
CopyCode.propTypes = {
|
||||||
arduino: PropTypes.string.isRequired,
|
arduino: PropTypes.string.isRequired,
|
||||||
name: PropTypes.string,
|
name: PropTypes.string,
|
||||||
workspaceName: PropTypes.func.isRequired
|
workspaceName: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = (state) => ({
|
||||||
arduino: state.workspace.code.arduino,
|
arduino: state.workspace.code.arduino,
|
||||||
name: state.workspace.name
|
name: state.workspace.name,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, { workspaceName })(
|
||||||
export default connect(mapStateToProps, { workspaceName })(withStyles(styles, { withTheme: true })(CopyCode));
|
withStyles(styles, { withTheme: true })(CopyCode)
|
||||||
|
);
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from "react";
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from "prop-types";
|
||||||
import { connect } from 'react-redux';
|
import { connect } from "react-redux";
|
||||||
|
|
||||||
import * as Blockly from 'blockly/core';
|
import * as Blockly from "blockly/core";
|
||||||
|
|
||||||
import { saveAs } from 'file-saver';
|
import { saveAs } from "file-saver";
|
||||||
|
|
||||||
import { detectWhitespacesAndReturnReadableResult } from '../../helpers/whitespace';
|
import { detectWhitespacesAndReturnReadableResult } from "../../helpers/whitespace";
|
||||||
|
|
||||||
import { withStyles } from '@material-ui/core/styles';
|
import { withStyles } from "@material-ui/core/styles";
|
||||||
import IconButton from '@material-ui/core/IconButton';
|
import IconButton from "@material-ui/core/IconButton";
|
||||||
import Tooltip from '@material-ui/core/Tooltip';
|
import Tooltip from "@material-ui/core/Tooltip";
|
||||||
|
|
||||||
import { faCamera } from "@fortawesome/free-solid-svg-icons";
|
import { faCamera } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
@ -19,18 +19,16 @@ const styles = (theme) => ({
|
|||||||
button: {
|
button: {
|
||||||
backgroundColor: theme.palette.primary.main,
|
backgroundColor: theme.palette.primary.main,
|
||||||
color: theme.palette.primary.contrastText,
|
color: theme.palette.primary.contrastText,
|
||||||
width: '40px',
|
width: "40px",
|
||||||
height: '40px',
|
height: "40px",
|
||||||
'&:hover': {
|
"&:hover": {
|
||||||
backgroundColor: theme.palette.primary.main,
|
backgroundColor: theme.palette.primary.main,
|
||||||
color: theme.palette.primary.contrastText,
|
color: theme.palette.primary.contrastText,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
class Screenshot extends Component {
|
class Screenshot extends Component {
|
||||||
|
|
||||||
getSvg = () => {
|
getSvg = () => {
|
||||||
const workspace = Blockly.getMainWorkspace();
|
const workspace = Blockly.getMainWorkspace();
|
||||||
var canvas = workspace.svgBlockCanvas_.cloneNode(true);
|
var canvas = workspace.svgBlockCanvas_.cloneNode(true);
|
||||||
@ -39,10 +37,12 @@ class Screenshot extends Component {
|
|||||||
canvas.removeAttribute("transform");
|
canvas.removeAttribute("transform");
|
||||||
// does not work in react
|
// does not work in react
|
||||||
// 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, ".");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ensure that fill-opacity is 1, because there cannot be a replacing
|
// ensure that fill-opacity is 1, because there cannot be a replacing
|
||||||
@ -56,19 +56,24 @@ class Screenshot extends Component {
|
|||||||
.blocklyPathLight {
|
.blocklyPathLight {
|
||||||
display: flex;
|
display: flex;
|
||||||
} `;
|
} `;
|
||||||
var css = '<defs><style type="text/css" xmlns="http://www.w3.org/1999/xhtml"><![CDATA[' + cssContent + ']]></style></defs>';
|
var css =
|
||||||
var bbox = document.getElementsByClassName("blocklyBlockCanvas")[0].getBBox();
|
'<defs><style type="text/css" xmlns="http://www.w3.org/1999/xhtml"><![CDATA[' +
|
||||||
|
cssContent +
|
||||||
|
"]]></style></defs>";
|
||||||
|
var bbox = document
|
||||||
|
.getElementsByClassName("blocklyBlockCanvas")[0]
|
||||||
|
.getBBox();
|
||||||
var content = new XMLSerializer().serializeToString(canvas);
|
var content = new XMLSerializer().serializeToString(canvas);
|
||||||
var xml = `<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
var xml = `<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
width="${bbox.width}" height="${bbox.height}" viewBox="${bbox.x} ${bbox.y} ${bbox.width} ${bbox.height}">
|
width="${bbox.width}" height="${bbox.height}" viewBox="${bbox.x} ${bbox.y} ${bbox.width} ${bbox.height}">
|
||||||
${css}">${content}</svg>`;
|
${css}">${content}</svg>`;
|
||||||
var fileName = detectWhitespacesAndReturnReadableResult(this.props.name);
|
var fileName = detectWhitespacesAndReturnReadableResult(this.props.name);
|
||||||
// this.props.workspaceName(this.state.name);
|
// this.props.workspaceName(this.state.name);
|
||||||
fileName = `${fileName}.svg`
|
fileName = `${fileName}.svg`;
|
||||||
var blob = new Blob([xml], { type: 'image/svg+xml;base64' });
|
var blob = new Blob([xml], { type: "image/svg+xml;base64" });
|
||||||
saveAs(blob, fileName);
|
saveAs(blob, fileName);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
@ -83,15 +88,18 @@ class Screenshot extends Component {
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Screenshot.propTypes = {
|
Screenshot.propTypes = {
|
||||||
name: PropTypes.string.isRequired,
|
name: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = (state) => ({
|
||||||
name: state.workspace.name,
|
name: state.workspace.name,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps, null)(withStyles(styles, { withTheme: true })(Screenshot));
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
null
|
||||||
|
)(withStyles(styles, { withTheme: true })(Screenshot));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user