cleanup code and update some packages
This commit is contained in:
		
							parent
							
								
									557d66d7d6
								
							
						
					
					
						commit
						b44d858fe6
					
				
							
								
								
									
										17487
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										17487
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										27
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								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 ( |               return ( | ||||||
|             <div style={{ marginTop: '10px' }}> |                 <div style={{ marginTop: "10px" }}> | ||||||
|               <Grid container className={!this.props.value || this.props.error ? this.props.classes.errorBorder : null}> |                   <Grid | ||||||
|  |                     container | ||||||
|  |                     className={ | ||||||
|  |                       !this.props.value || this.props.error | ||||||
|  |                         ? this.props.classes.errorBorder | ||||||
|  |                         : null | ||||||
|  |                     } | ||||||
|  |                   > | ||||||
|                     <Grid item xs={12}> |                     <Grid item xs={12}> | ||||||
|                       <BlocklyWindow |                       <BlocklyWindow | ||||||
|                         blockDisabled={this.props.task} |                         blockDisabled={this.props.task} | ||||||
|                         trashcan={false} |                         trashcan={false} | ||||||
|                         initialXml={this.state.xml} |                         initialXml={this.state.xml} | ||||||
|                     blocklyCSS={{ height: '500px' }} |                         blocklyCSS={{ height: "500px" }} | ||||||
|                       /> |                       /> | ||||||
|                     </Grid> |                     </Grid> | ||||||
|                   </Grid> |                   </Grid> | ||||||
|                   <Button |                   <Button | ||||||
|                 className={!this.props.value || this.props.error ? this.props.classes.errorButton : null} |                     className={ | ||||||
|                 style={{ marginTop: '5px', height: '40px' }} |                       !this.props.value || this.props.error | ||||||
|                 variant='contained' |                         ? this.props.classes.errorButton | ||||||
|                 color='primary' |                         : null | ||||||
|  |                     } | ||||||
|  |                     style={{ marginTop: "5px", height: "40px" }} | ||||||
|  |                     variant="contained" | ||||||
|  |                     color="primary" | ||||||
|                     disabled={this.state.disabled} |                     disabled={this.state.disabled} | ||||||
|                     onClick={() => this.setXml()} |                     onClick={() => this.setXml()} | ||||||
|                   > |                   > | ||||||
|                 {this.props.task ? Blockly.Msg.builder_solution_submit : Blockly.Msg.builder_example_submit} |                     {this.props.task | ||||||
|  |                       ? Blockly.Msg.builder_solution_submit | ||||||
|  |                       : Blockly.Msg.builder_example_submit} | ||||||
|                   </Button> |                   </Button> | ||||||
|                 </div> |                 </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 { | ||||||
|     else { |       window.localStorage.removeItem("news"); | ||||||
|       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,47 +1,44 @@ | |||||||
| 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: { |   iconButton: { | ||||||
|     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, | ||||||
|         } |     }, | ||||||
|   }, |   }, | ||||||
|   button: { |   button: { | ||||||
|     backgroundColor: theme.palette.button.copycode, |     backgroundColor: theme.palette.button.copycode, | ||||||
|     color: theme.palette.primary.contrastText, |     color: theme.palette.primary.contrastText, | ||||||
|         '&:hover': { |     "&:hover": { | ||||||
|       backgroundColor: theme.palette.button.copycode, |       backgroundColor: theme.palette.button.copycode, | ||||||
|       color: theme.palette.primary.contrastText, |       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 = { | ||||||
| @ -49,51 +46,65 @@ class CopyCode extends Component { | |||||||
|     }; |     }; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|   copyCode = () => { |   copyCode = () => { | ||||||
|         navigator.clipboard.writeText(this.props.arduino) |     navigator.clipboard.writeText(this.props.arduino); | ||||||
|         this.setState({ snackbar: true, type: 'success', key: Date.now(), message: Blockly.Msg.messages_copy_code }); |     this.setState({ | ||||||
|     } |       snackbar: true, | ||||||
|  |       type: "success", | ||||||
|  |       key: Date.now(), | ||||||
|  |       message: Blockly.Msg.messages_copy_code, | ||||||
|  |     }); | ||||||
|  |   }; | ||||||
| 
 | 
 | ||||||
|   render() { |   render() { | ||||||
|     return ( |     return ( | ||||||
|       <div style={{}}> |       <div style={{}}> | ||||||
|                 {this.props.iconButton ? |         {this.props.iconButton ? ( | ||||||
|                     <Tooltip title={Blockly.Msg.tooltip_copy_code} arrow style={{ marginRight: '5px' }}> |           <Tooltip | ||||||
|  |             title={Blockly.Msg.tooltip_copy_code} | ||||||
|  |             arrow | ||||||
|  |             style={{ marginRight: "5px" }} | ||||||
|  |           > | ||||||
|             <IconButton |             <IconButton | ||||||
|               className={`copyCode ${this.props.classes.iconButton}`} |               className={`copyCode ${this.props.classes.iconButton}`} | ||||||
|               onClick={() => this.copyCode()} |               onClick={() => this.copyCode()} | ||||||
|             > |             > | ||||||
|                             <FontAwesomeIcon icon={faCopy} size="l" /> |               <FontAwesomeIcon icon={faCopy} size="m" /> | ||||||
|             </IconButton> |             </IconButton> | ||||||
|           </Tooltip> |           </Tooltip> | ||||||
|                     : |         ) : ( | ||||||
|                     <Button style={{ float: 'right', color: 'white' }} variant="contained" className={this.props.classes.button} onClick={() => this.copyCode()}> |           <Button | ||||||
|                         <FontAwesomeIcon icon={faCopy} style={{ marginRight: '5px' }} /> Code kopieren |             style={{ float: "right", color: "white" }} | ||||||
|  |             variant="contained" | ||||||
|  |             className={this.props.classes.button} | ||||||
|  |             onClick={() => this.copyCode()} | ||||||
|  |           > | ||||||
|  |             <FontAwesomeIcon icon={faCopy} style={{ marginRight: "5px" }} />{" "} | ||||||
|  |             Code kopieren | ||||||
|           </Button> |           </Button> | ||||||
|                 } |         )} | ||||||
|         <Snackbar |         <Snackbar | ||||||
|           open={this.state.snackbar} |           open={this.state.snackbar} | ||||||
|           message={this.state.message} |           message={this.state.message} | ||||||
|           type={this.state.type} |           type={this.state.type} | ||||||
|           key={this.state.key} |           key={this.state.key} | ||||||
|         /> |         /> | ||||||
| 
 |       </div> | ||||||
|             </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