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", | ||||
|   "private": true, | ||||
|   "dependencies": { | ||||
|     "@blockly/block-plus-minus": "^2.0.39", | ||||
|     "@blockly/field-slider": "^2.1.30", | ||||
|     "@blockly/plugin-scroll-options": "^1.0.4", | ||||
|     "@blockly/plugin-typed-variable-modal": "^3.1.29", | ||||
|     "@blockly/workspace-backpack": "^1.0.12", | ||||
|     "@blockly/zoom-to-fit": "^2.0.9", | ||||
|     "@blockly/block-plus-minus": "^3.0.5", | ||||
|     "@blockly/field-slider": "^3.0.5", | ||||
|     "@blockly/plugin-scroll-options": "^2.0.5", | ||||
|     "@blockly/plugin-typed-variable-modal": "^4.0.5", | ||||
|     "@blockly/workspace-backpack": "^1.0.14", | ||||
|     "@blockly/zoom-to-fit": "^2.0.14", | ||||
|     "@fortawesome/fontawesome-svg-core": "^1.2.30", | ||||
|     "@fortawesome/free-solid-svg-icons": "^5.14.0", | ||||
|     "@fortawesome/react-fontawesome": "^0.1.11", | ||||
| @ -26,18 +26,23 @@ | ||||
|     "moment": "^2.28.0", | ||||
|     "prismjs": "^1.25.0", | ||||
|     "react": "^17.0.2", | ||||
|     "react-cookie-consent": "^5.2.0", | ||||
|     "react-cookie-consent": "^7.2.1", | ||||
|     "react-dom": "^17.0.2", | ||||
|     "react-markdown": "^5.0.2", | ||||
|     "react-mde": "^11.5.0", | ||||
|     "react-redux": "^7.2.4", | ||||
|     "react-router-dom": "^5.2.0", | ||||
|     "react-scripts": "^4.0.3", | ||||
|     "reactour": "^1.18.0", | ||||
|     "reactour": "^1.18.7", | ||||
|     "redux": "^4.0.5", | ||||
|     "redux-thunk": "^2.3.0", | ||||
|     "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": { | ||||
|     "start": "react-scripts start", | ||||
| @ -49,11 +54,9 @@ | ||||
|   "eslintConfig": { | ||||
|     "extends": "react-app" | ||||
|   }, | ||||
|   "browserslist":  | ||||
|     [ | ||||
|       ">0.2%", | ||||
|       "not dead", | ||||
|       "not op_mini all" | ||||
|     ] | ||||
|    | ||||
|   "browserslist": [ | ||||
|     ">0.2%", | ||||
|     "not dead", | ||||
|     "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 { Provider } from 'react-redux'; | ||||
| import store from './store'; | ||||
| import { loadUser } from './actions/authActions'; | ||||
| import { Provider } from "react-redux"; | ||||
| import store from "./store"; | ||||
| 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: { | ||||
|     primary: { | ||||
|       main: '#4EAF47', | ||||
|       contrastText: '#ffffff' | ||||
|       main: "#4EAF47", | ||||
|       contrastText: "#ffffff", | ||||
|     }, | ||||
|     secondary: { | ||||
|       main: '#DDDDDD' | ||||
|       main: "#DDDDDD", | ||||
|     }, | ||||
|     button: { | ||||
|       compile: '#e27136' | ||||
|     } | ||||
|   } | ||||
|       compile: "#e27136", | ||||
|     }, | ||||
|   }, | ||||
| }); | ||||
| 
 | ||||
| class App extends Component { | ||||
| 
 | ||||
|   componentDidMount() { | ||||
|     store.dispatch(loadUser()); | ||||
|   } | ||||
|  | ||||
| @ -24,7 +24,6 @@ const CodeEditor = (props) => { | ||||
|   const [time, setTime] = useState(null); | ||||
|   const [value, setValue] = useState(""); | ||||
|   const [resetDialog, setResetDialog] = useState(false); | ||||
|   const [blocklyCode, setBlocklyCode] = useState(""); | ||||
|   const [defaultValue, setDefaultValue] = useState( | ||||
|     localStorage.getItem("ArduinoCode") | ||||
|       ? localStorage.getItem("ArduinoCode") | ||||
| @ -62,7 +61,6 @@ void loop() { | ||||
|         setProgress(false); | ||||
|         const result = data.data.id; | ||||
|         setId(result); | ||||
|         console.log(result); | ||||
|         const filename = "sketch"; | ||||
|         window.open( | ||||
|           `${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); | ||||
|   }; | ||||
| 
 | ||||
|   const handleClose = (event, reason) => { | ||||
|     if (reason === "clickaway") { | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     setOpen(false); | ||||
|   }; | ||||
| 
 | ||||
|   const getBlocklyCode = () => { | ||||
|     var code = store.getState().workspace.code.arduino; | ||||
|     editorRef.current.setValue(code); | ||||
|  | ||||
| @ -190,7 +190,7 @@ class Compile extends Component { | ||||
|               className={`compileBlocks ${this.props.classes.iconButton}`} | ||||
|               onClick={() => this.compile()} | ||||
|             > | ||||
|               <FontAwesomeIcon icon={faClipboardCheck} size="l" /> | ||||
|               <FontAwesomeIcon icon={faClipboardCheck} size="m" /> | ||||
|             </IconButton> | ||||
|           </Tooltip> | ||||
|         ) : ( | ||||
|  | ||||
| @ -25,19 +25,6 @@ const Sidebar = () => { | ||||
| 
 | ||||
|   const monaco = useMonaco(); | ||||
|   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); | ||||
|   }; | ||||
| 
 | ||||
|  | ||||
| @ -11,7 +11,6 @@ import { Card } from "@material-ui/core"; | ||||
| import * as Blockly from "blockly"; | ||||
| import { default as MonacoEditor } from "@monaco-editor/react"; | ||||
| 
 | ||||
| 
 | ||||
| const Accordion = withStyles((theme) => ({ | ||||
|   root: { | ||||
|     border: `1px solid ${theme.palette.secondary.main}`, | ||||
| @ -134,7 +133,7 @@ class CodeViewer extends Component { | ||||
|               options={{ | ||||
|                 readOnly: true, | ||||
| 
 | ||||
|                 fontSize: "12px", | ||||
|                 fontSize: "16px", | ||||
|               }} | ||||
|             /> | ||||
|           </AccordionDetails> | ||||
|  | ||||
| @ -54,12 +54,17 @@ class Home extends Component { | ||||
|       key: "", | ||||
|       message: "", | ||||
|       open: true, | ||||
|       resumeWork: false, | ||||
|       initialXml: localStorage.getItem("autoSaveXML"), | ||||
|     }; | ||||
|   } | ||||
| 
 | ||||
|   componentDidMount() { | ||||
|     console.log(this.props.platform); | ||||
|     if (this.state.initialXml) { | ||||
|       this.setState({ resumeWork: true }); | ||||
|     } else { | ||||
|       console.log("new work"); | ||||
|     } | ||||
|     if (this.props.platform === true) { | ||||
|       this.setState({ codeOn: false }); | ||||
|     } | ||||
| @ -95,6 +100,10 @@ class Home extends Component { | ||||
|     this.setState({ open: !this.state }); | ||||
|   }; | ||||
| 
 | ||||
|   toogleResumeWork = () => { | ||||
|     this.setState({ resumeWork: !this.state.resumeWork }); | ||||
|   }; | ||||
| 
 | ||||
|   onChangeCheckbox = (e) => { | ||||
|     if (e.target.checked) { | ||||
|       window.localStorage.setItem("ota", e.target.checked); | ||||
| @ -188,6 +197,25 @@ class Home extends Component { | ||||
|           ) : null} | ||||
|         </Grid> | ||||
|         <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 ? ( | ||||
|           <Dialog | ||||
|             style={{ zIndex: 9999999 }} | ||||
| @ -223,7 +251,7 @@ Home.propTypes = { | ||||
|   workspaceName: PropTypes.func.isRequired, | ||||
|   message: PropTypes.object.isRequired, | ||||
|   statistics: PropTypes.bool.isRequired, | ||||
|   platform: PropTypes.object.isRequired, | ||||
|   platform: PropTypes.bool.isRequired, | ||||
| }; | ||||
| 
 | ||||
| const mapStateToProps = (state) => ({ | ||||
|  | ||||
| @ -359,9 +359,9 @@ class Navbar extends Component { | ||||
| Navbar.propTypes = { | ||||
|   tutorialIsLoading: PropTypes.bool.isRequired, | ||||
|   projectIsLoading: PropTypes.bool.isRequired, | ||||
|   isAuthenticated: PropTypes.bool.isRequired, | ||||
|   isAuthenticated: PropTypes.bool, | ||||
|   user: PropTypes.object, | ||||
|   tutorial: PropTypes.object.isRequired, | ||||
|   tutorial: PropTypes.object, | ||||
|   activeStep: PropTypes.number.isRequired, | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -104,7 +104,7 @@ class Routes extends Component { | ||||
| } | ||||
| 
 | ||||
| Home.propTypes = { | ||||
|   visitPage: PropTypes.func.isRequired, | ||||
|   visitPage: PropTypes.func, | ||||
| }; | ||||
| 
 | ||||
| export default connect(null, { visitPage })(withRouter(Routes)); | ||||
|  | ||||
| @ -1,53 +1,57 @@ | ||||
| import React, { Component } from 'react'; | ||||
| import PropTypes from 'prop-types'; | ||||
| import { connect } from 'react-redux'; | ||||
| import { changeContent, deleteProperty, setError, deleteError } from '../../../actions/tutorialBuilderActions'; | ||||
| import React, { Component } from "react"; | ||||
| import PropTypes from "prop-types"; | ||||
| import { connect } from "react-redux"; | ||||
| import { | ||||
|   changeContent, | ||||
|   deleteProperty, | ||||
|   setError, | ||||
|   deleteError, | ||||
| } from "../../../actions/tutorialBuilderActions"; | ||||
| 
 | ||||
| import moment from 'moment'; | ||||
| import localization from 'moment/locale/de'; | ||||
| import * as Blockly from 'blockly/core'; | ||||
| import moment from "moment"; | ||||
| import localization from "moment/locale/de"; | ||||
| import * as Blockly from "blockly/core"; | ||||
| 
 | ||||
| import { initialXml } from '../../Blockly//initialXml.js'; | ||||
| import BlocklyWindow from '../../Blockly/BlocklyWindow'; | ||||
| import { initialXml } from "../../Blockly//initialXml.js"; | ||||
| import BlocklyWindow from "../../Blockly/BlocklyWindow"; | ||||
| 
 | ||||
| import { withStyles } from '@material-ui/core/styles'; | ||||
| import Switch from '@material-ui/core/Switch'; | ||||
| import FormControlLabel from '@material-ui/core/FormControlLabel'; | ||||
| import FormHelperText from '@material-ui/core/FormHelperText'; | ||||
| import FormLabel from '@material-ui/core/FormLabel'; | ||||
| import Button from '@material-ui/core/Button'; | ||||
| import Grid from '@material-ui/core/Grid'; | ||||
| import { withStyles } from "@material-ui/core/styles"; | ||||
| import Switch from "@material-ui/core/Switch"; | ||||
| import FormControlLabel from "@material-ui/core/FormControlLabel"; | ||||
| import FormHelperText from "@material-ui/core/FormHelperText"; | ||||
| import FormLabel from "@material-ui/core/FormLabel"; | ||||
| import Button from "@material-ui/core/Button"; | ||||
| import Grid from "@material-ui/core/Grid"; | ||||
| 
 | ||||
| const styles = (theme) => ({ | ||||
|   errorColor: { | ||||
|     color: theme.palette.error.dark | ||||
|     color: theme.palette.error.dark, | ||||
|   }, | ||||
|   errorBorder: { | ||||
|     border: `1px solid ${theme.palette.error.dark}` | ||||
|     border: `1px solid ${theme.palette.error.dark}`, | ||||
|   }, | ||||
|   errorButton: { | ||||
|     marginTop: '5px', | ||||
|     height: '40px', | ||||
|     marginTop: "5px", | ||||
|     height: "40px", | ||||
|     backgroundColor: theme.palette.error.dark, | ||||
|     '&:hover': { | ||||
|       backgroundColor: theme.palette.error.dark | ||||
|     } | ||||
|   } | ||||
|     "&:hover": { | ||||
|       backgroundColor: theme.palette.error.dark, | ||||
|     }, | ||||
|   }, | ||||
| }); | ||||
| 
 | ||||
| class BlocklyExample extends Component { | ||||
| 
 | ||||
|   constructor(props) { | ||||
|     super(props); | ||||
|     this.state = { | ||||
|       checked: props.task ? props.task : props.value ? true : false, | ||||
|       input: null, | ||||
|       disabled: false | ||||
|       disabled: false, | ||||
|     }; | ||||
|   } | ||||
| 
 | ||||
|   componentDidMount() { | ||||
|     moment.updateLocale('de', localization); | ||||
|     moment.updateLocale("de", localization); | ||||
|     this.isError(); | ||||
|     // if(this.props.task){
 | ||||
|     //   this.props.setError(this.props.index, 'xml');
 | ||||
| @ -56,7 +60,14 @@ class BlocklyExample extends Component { | ||||
| 
 | ||||
|   componentDidUpdate(props, state) { | ||||
|     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() | ||||
|       ); | ||||
|     } | ||||
| @ -77,12 +88,11 @@ class BlocklyExample extends Component { | ||||
|       // check if value is valid xml;
 | ||||
|       try { | ||||
|         Blockly.Xml.textToDom(xml); | ||||
|         this.props.deleteError(this.props.index, 'xml'); | ||||
|       } | ||||
|       catch (err) { | ||||
|         this.props.deleteError(this.props.index, "xml"); | ||||
|       } catch (err) { | ||||
|         xml = initialXml; | ||||
|         // 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) { | ||||
|         // 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"'); | ||||
|       } | ||||
|       this.setState({ xml: xml }); | ||||
|     } else { | ||||
|       this.props.deleteError(this.props.index, "xml"); | ||||
|     } | ||||
|     else { | ||||
|       this.props.deleteError(this.props.index, 'xml'); | ||||
|     } | ||||
|   } | ||||
|   }; | ||||
| 
 | ||||
|   onChange = (value) => { | ||||
|     var oldValue = this.state.checked; | ||||
|     this.setState({ checked: value }); | ||||
|     if (oldValue !== value && !value) { | ||||
|       this.props.deleteError(this.props.index, 'xml'); | ||||
|       this.props.deleteProperty(this.props.index, 'xml'); | ||||
|       this.props.deleteError(this.props.index, "xml"); | ||||
|       this.props.deleteProperty(this.props.index, "xml"); | ||||
|     } | ||||
|   } | ||||
|   }; | ||||
| 
 | ||||
|   setXml = () => { | ||||
|     var xml = this.props.xml; | ||||
|     this.props.changeContent(xml, this.props.index, 'xml'); | ||||
|     this.setState({ input: moment(Date.now()).format('LTS') }); | ||||
|   } | ||||
|     this.props.changeContent(xml, this.props.index, "xml"); | ||||
|     this.setState({ input: moment(Date.now()).format("LTS") }); | ||||
|   }; | ||||
| 
 | ||||
|   render() { | ||||
|     return ( | ||||
|       <div style={{ marginBottom: '10px', padding: '18.5px 14px', borderRadius: '25px', border: '1px solid lightgrey', width: 'calc(100% - 28px)' }}> | ||||
|         {!this.props.task ? | ||||
|       <div | ||||
|         style={{ | ||||
|           marginBottom: "10px", | ||||
|           padding: "18.5px 14px", | ||||
|           borderRadius: "25px", | ||||
|           border: "1px solid lightgrey", | ||||
|           width: "calc(100% - 28px)", | ||||
|         }} | ||||
|       > | ||||
|         {!this.props.task ? ( | ||||
|           <FormControlLabel | ||||
|             labelPlacement="end" | ||||
|             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 ? | ||||
|           <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} | ||||
|         ) : ( | ||||
|           <FormLabel style={{ color: "black" }}> | ||||
|             {Blockly.Msg.builder_solution} | ||||
|           </FormLabel> | ||||
|         )} | ||||
|         {this.state.checked ? ( | ||||
|           !this.props.value || this.props.error ? ( | ||||
|             <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 */} | ||||
|         {this.state.checked && this.state.xml ? (() => { | ||||
|           return ( | ||||
|             <div style={{ marginTop: '10px' }}> | ||||
|               <Grid container className={!this.props.value || this.props.error ? this.props.classes.errorBorder : null}> | ||||
|                 <Grid item xs={12}> | ||||
|                   <BlocklyWindow | ||||
|                     blockDisabled={this.props.task} | ||||
|                     trashcan={false} | ||||
|                     initialXml={this.state.xml} | ||||
|                     blocklyCSS={{ height: '500px' }} | ||||
|                   /> | ||||
|                 </Grid> | ||||
|               </Grid> | ||||
|               <Button | ||||
|                 className={!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> | ||||
|           ) | ||||
|         })() | ||||
|         {this.state.checked && this.state.xml | ||||
|           ? (() => { | ||||
|               return ( | ||||
|                 <div style={{ marginTop: "10px" }}> | ||||
|                   <Grid | ||||
|                     container | ||||
|                     className={ | ||||
|                       !this.props.value || this.props.error | ||||
|                         ? this.props.classes.errorBorder | ||||
|                         : null | ||||
|                     } | ||||
|                   > | ||||
|                     <Grid item xs={12}> | ||||
|                       <BlocklyWindow | ||||
|                         blockDisabled={this.props.task} | ||||
|                         trashcan={false} | ||||
|                         initialXml={this.state.xml} | ||||
|                         blocklyCSS={{ height: "500px" }} | ||||
|                       /> | ||||
|                     </Grid> | ||||
|                   </Grid> | ||||
|                   <Button | ||||
|                     className={ | ||||
|                       !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} | ||||
|       </div> | ||||
|     ); | ||||
|   }; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| BlocklyExample.propTypes = { | ||||
| @ -172,12 +221,16 @@ BlocklyExample.propTypes = { | ||||
|   deleteProperty: PropTypes.func.isRequired, | ||||
|   setError: PropTypes.func.isRequired, | ||||
|   deleteError: PropTypes.func.isRequired, | ||||
|   xml: PropTypes.string.isRequired | ||||
|   xml: PropTypes.string.isRequired, | ||||
| }; | ||||
| 
 | ||||
| const mapStateToProps = state => ({ | ||||
|   xml: state.workspace.code.xml | ||||
| const mapStateToProps = (state) => ({ | ||||
|   xml: state.workspace.code.xml, | ||||
| }); | ||||
| 
 | ||||
| 
 | ||||
| export default connect(mapStateToProps, { changeContent, deleteProperty, setError, deleteError })(withStyles(styles, { withTheme: true })(BlocklyExample)); | ||||
| export default connect(mapStateToProps, { | ||||
|   changeContent, | ||||
|   deleteProperty, | ||||
|   setError, | ||||
|   deleteError, | ||||
| })(withStyles(styles, { withTheme: true })(BlocklyExample)); | ||||
|  | ||||
| @ -1,75 +1,79 @@ | ||||
| import React, { Component } from 'react'; | ||||
| import PropTypes from 'prop-types'; | ||||
| import { connect } from 'react-redux'; | ||||
| import Dialog from '../Dialog'; | ||||
| import React, { Component } from "react"; | ||||
| import PropTypes from "prop-types"; | ||||
| import { connect } from "react-redux"; | ||||
| import Dialog from "../Dialog"; | ||||
| 
 | ||||
| import { withStyles } from '@material-ui/core/styles'; | ||||
| import Checkbox from '@material-ui/core/Checkbox'; | ||||
| import FormControlLabel from '@material-ui/core/FormControlLabel'; | ||||
| import * as Blockly from 'blockly' | ||||
| import ReactMarkdown from 'react-markdown'; | ||||
| import { withStyles } from "@material-ui/core/styles"; | ||||
| import Checkbox from "@material-ui/core/Checkbox"; | ||||
| import FormControlLabel from "@material-ui/core/FormControlLabel"; | ||||
| import * as Blockly from "blockly"; | ||||
| import ReactMarkdown from "react-markdown"; | ||||
| 
 | ||||
| const styles = (theme) => ({ | ||||
|   link: { | ||||
|     color: theme.palette.primary.main, | ||||
|     textDecoration: 'none', | ||||
|     '&:hover': { | ||||
|     textDecoration: "none", | ||||
|     "&:hover": { | ||||
|       color: theme.palette.primary.main, | ||||
|       textDecoration: `underline` | ||||
|     } | ||||
|       textDecoration: `underline`, | ||||
|     }, | ||||
|   }, | ||||
|   label: { | ||||
|     fontSize: '0.9rem', | ||||
|     color: 'grey' | ||||
|   } | ||||
|     fontSize: "0.9rem", | ||||
|     color: "grey", | ||||
|   }, | ||||
| }); | ||||
| 
 | ||||
| class HintTutorialExists extends Component { | ||||
| 
 | ||||
|   constructor(props) { | ||||
|     var previousPageWasAnotherDomain = props.pageVisits === 0; | ||||
|     var userDoNotWantToSeeNews = window.localStorage.getItem('news') ? true : false; | ||||
|     var userDoNotWantToSeeNews = window.localStorage.getItem("news") | ||||
|       ? true | ||||
|       : false; | ||||
|     super(props); | ||||
|     this.state = { | ||||
|       open: userDoNotWantToSeeNews ? !userDoNotWantToSeeNews : previousPageWasAnotherDomain | ||||
|       open: userDoNotWantToSeeNews | ||||
|         ? !userDoNotWantToSeeNews | ||||
|         : previousPageWasAnotherDomain, | ||||
|     }; | ||||
|   } | ||||
| 
 | ||||
|   toggleDialog = () => { | ||||
|     this.setState({ open: !this.state }); | ||||
|   } | ||||
|   }; | ||||
| 
 | ||||
|   onChange = (e) => { | ||||
|     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() { | ||||
|     return ( | ||||
|       <Dialog | ||||
|         style={{ zIndex: 9999999 }} | ||||
|         fullWidth | ||||
|         maxWidth={'sm'} | ||||
|         maxWidth={"sm"} | ||||
|         open={this.state.open} | ||||
|         title={Blockly.Msg.messages_newblockly_head} | ||||
|         content={''} | ||||
|         content={""} | ||||
|         onClose={this.toggleDialog} | ||||
|         onClick={this.toggleDialog} | ||||
|         button={Blockly.Msg.button_close} | ||||
|       > | ||||
|         <div> | ||||
|           <ReactMarkdown linkTarget="_blank">{Blockly.Msg.messages_newblockly_text}</ReactMarkdown> | ||||
|           <ReactMarkdown linkTarget="_blank"> | ||||
|             {Blockly.Msg.messages_newblockly_text} | ||||
|           </ReactMarkdown> | ||||
|         </div> | ||||
|         <FormControlLabel | ||||
|           style={{ marginTop: '20px' }} | ||||
|           style={{ marginTop: "20px" }} | ||||
|           classes={{ label: this.props.classes.label }} | ||||
|           control={ | ||||
|             <Checkbox | ||||
|               size={'small'} | ||||
|               size={"small"} | ||||
|               value={true} | ||||
|               checked={this.state.checked} | ||||
|               onChange={(e) => this.onChange(e)} | ||||
| @ -81,15 +85,18 @@ class HintTutorialExists extends Component { | ||||
|         /> | ||||
|       </Dialog> | ||||
|     ); | ||||
|   }; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| HintTutorialExists.propTypes = { | ||||
|   pageVisits: PropTypes.number.isRequired | ||||
|   pageVisits: PropTypes.number.isRequired, | ||||
| }; | ||||
| 
 | ||||
| const mapStateToProps = state => ({ | ||||
|   pageVisits: state.general.pageVisits | ||||
| const mapStateToProps = (state) => ({ | ||||
|   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 PropTypes from 'prop-types'; | ||||
| import { connect } from 'react-redux'; | ||||
| import { tutorialCheck, tutorialStep } from '../../actions/tutorialActions'; | ||||
| import React, { Component } from "react"; | ||||
| import PropTypes from "prop-types"; | ||||
| import { connect } from "react-redux"; | ||||
| import { tutorialCheck, tutorialStep } from "../../actions/tutorialActions"; | ||||
| 
 | ||||
| import { withRouter } from 'react-router-dom'; | ||||
| import { withRouter } from "react-router-dom"; | ||||
| 
 | ||||
| import Compile from '../Workspace/Compile'; | ||||
| import Dialog from '../Dialog'; | ||||
| import Compile from "../Workspace/Compile"; | ||||
| import Dialog from "../Dialog"; | ||||
| 
 | ||||
| import { checkXml } from '../../helpers/compareXml'; | ||||
| import { checkXml } from "../../helpers/compareXml"; | ||||
| 
 | ||||
| import { withStyles } from '@material-ui/core/styles'; | ||||
| import IconButton from '@material-ui/core/IconButton'; | ||||
| import Tooltip from '@material-ui/core/Tooltip'; | ||||
| import Button from '@material-ui/core/Button'; | ||||
| import { withStyles } from "@material-ui/core/styles"; | ||||
| import IconButton from "@material-ui/core/IconButton"; | ||||
| import Tooltip from "@material-ui/core/Tooltip"; | ||||
| import Button from "@material-ui/core/Button"; | ||||
| 
 | ||||
| import { faClipboardCheck } from "@fortawesome/free-solid-svg-icons"; | ||||
| import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||||
| 
 | ||||
| import * as Blockly from 'blockly' | ||||
| import * as Blockly from "blockly"; | ||||
| 
 | ||||
| const styles = (theme) => ({ | ||||
|   compile: { | ||||
|     backgroundColor: theme.palette.button.compile, | ||||
|     color: theme.palette.primary.contrastText, | ||||
|     '&:hover': { | ||||
|     "&:hover": { | ||||
|       backgroundColor: theme.palette.button.compile, | ||||
|       color: theme.palette.primary.contrastText, | ||||
|     } | ||||
|   } | ||||
|     }, | ||||
|   }, | ||||
| }); | ||||
| 
 | ||||
| class SolutionCheck extends Component { | ||||
| 
 | ||||
|   state = { | ||||
|     open: false, | ||||
|     msg: '' | ||||
|   } | ||||
|     msg: "", | ||||
|   }; | ||||
| 
 | ||||
|   toggleDialog = () => { | ||||
|     if (this.state.open) { | ||||
|       this.setState({ open: false, msg: '' }); | ||||
|     } | ||||
|     else { | ||||
|       this.setState({ open: false, msg: "" }); | ||||
|     } else { | ||||
|       this.setState({ open: !this.state }); | ||||
|     } | ||||
|   } | ||||
|   }; | ||||
| 
 | ||||
|   check = () => { | ||||
|     const tutorial = this.props.tutorial; | ||||
| @ -53,7 +51,7 @@ class SolutionCheck extends Component { | ||||
|     var msg = checkXml(step.xml, this.props.xml); | ||||
|     this.props.tutorialCheck(msg.type, step); | ||||
|     this.setState({ msg, open: true }); | ||||
|   } | ||||
|   }; | ||||
| 
 | ||||
|   render() { | ||||
|     const steps = this.props.tutorial.steps; | ||||
| @ -62,68 +60,74 @@ class SolutionCheck extends Component { | ||||
|         <Tooltip title={Blockly.Msg.tooltip_check_solution} arrow> | ||||
|           <IconButton | ||||
|             className={`solutionCheck ${this.props.classes.compile}`} | ||||
|             style={{ width: '40px', height: '40px', marginRight: '5px' }} | ||||
|             style={{ width: "40px", height: "40px", marginRight: "5px" }} | ||||
|             onClick={() => this.check()} | ||||
|           > | ||||
|             <FontAwesomeIcon icon={faClipboardCheck} size="l" /> | ||||
|             <FontAwesomeIcon icon={faClipboardCheck} size="m" /> | ||||
|           </IconButton> | ||||
|         </Tooltip> | ||||
| 
 | ||||
|         <Dialog | ||||
|           style={{ zIndex: 9999999 }} | ||||
|           fullWidth | ||||
|           maxWidth={'sm'} | ||||
|           maxWidth={"sm"} | ||||
|           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} | ||||
|           onClose={this.toggleDialog} | ||||
|           onClick={this.toggleDialog} | ||||
|           button={Blockly.Msg.button_close} | ||||
|         > | ||||
|           {this.state.msg.type === 'success' ? | ||||
|             <div style={{ marginTop: '20px', display: 'flex' }}> | ||||
|           {this.state.msg.type === "success" ? ( | ||||
|             <div style={{ marginTop: "20px", display: "flex" }}> | ||||
|               <Compile /> | ||||
|               {this.props.activeStep === steps.length - 1 ? | ||||
|               {this.props.activeStep === steps.length - 1 ? ( | ||||
|                 <Button | ||||
|                   style={{ marginLeft: '10px' }} | ||||
|                   style={{ marginLeft: "10px" }} | ||||
|                   variant="contained" | ||||
|                   color="primary" | ||||
|                   onClick={() => { this.toggleDialog(); this.props.history.push(`/tutorial/`) }} | ||||
|                   onClick={() => { | ||||
|                     this.toggleDialog(); | ||||
|                     this.props.history.push(`/tutorial/`); | ||||
|                   }} | ||||
|                 > | ||||
|                   {Blockly.Msg.button_tutorial_overview} | ||||
|                 </Button> | ||||
|                 : | ||||
|               ) : ( | ||||
|                 <Button | ||||
|                   style={{ marginLeft: '10px' }} | ||||
|                   style={{ marginLeft: "10px" }} | ||||
|                   variant="contained" | ||||
|                   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} | ||||
|                 </Button> | ||||
|               } | ||||
|               )} | ||||
|             </div> | ||||
|             : null} | ||||
|           ) : null} | ||||
|         </Dialog> | ||||
| 
 | ||||
|       </div> | ||||
|     ); | ||||
|   }; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| SolutionCheck.propTypes = { | ||||
|   tutorialCheck: PropTypes.func.isRequired, | ||||
|   tutorialStep: PropTypes.func.isRequired, | ||||
|   activeStep: PropTypes.number.isRequired, | ||||
|   xml: PropTypes.string.isRequired, | ||||
|   tutorial: PropTypes.object.isRequired | ||||
|   tutorial: PropTypes.object.isRequired, | ||||
| }; | ||||
| 
 | ||||
| const mapStateToProps = state => ({ | ||||
| const mapStateToProps = (state) => ({ | ||||
|   activeStep: state.tutorial.activeStep, | ||||
|   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}`} | ||||
|               onClick={() => this.compile()} | ||||
|             > | ||||
|               <FontAwesomeIcon icon={faClipboardCheck} size="l" /> | ||||
|               <FontAwesomeIcon icon={faClipboardCheck} size="m" /> | ||||
|             </IconButton> | ||||
|           </Tooltip> | ||||
|         ) : ( | ||||
|  | ||||
| @ -1,99 +1,110 @@ | ||||
| import React, { Component } from 'react'; | ||||
| import PropTypes from 'prop-types'; | ||||
| import { connect } from 'react-redux'; | ||||
| import { workspaceName } from '../../actions/workspaceActions'; | ||||
| import React, { Component } from "react"; | ||||
| import PropTypes from "prop-types"; | ||||
| import { connect } from "react-redux"; | ||||
| import { workspaceName } from "../../actions/workspaceActions"; | ||||
| 
 | ||||
| import { withStyles } from '@material-ui/core/styles'; | ||||
| import Button from '@material-ui/core/Button'; | ||||
| import IconButton from '@material-ui/core/IconButton'; | ||||
| import Tooltip from '@material-ui/core/Tooltip'; | ||||
| import { withStyles } from "@material-ui/core/styles"; | ||||
| import Button from "@material-ui/core/Button"; | ||||
| import IconButton from "@material-ui/core/IconButton"; | ||||
| import Tooltip from "@material-ui/core/Tooltip"; | ||||
| 
 | ||||
| import { faCopy } from "@fortawesome/free-solid-svg-icons"; | ||||
| import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||||
| import * as Blockly from 'blockly/core'; | ||||
| import Snackbar from '../Snackbar'; | ||||
| 
 | ||||
| import * as Blockly from "blockly/core"; | ||||
| import Snackbar from "../Snackbar"; | ||||
| 
 | ||||
| const styles = (theme) => ({ | ||||
|     backdrop: { | ||||
|         zIndex: theme.zIndex.drawer + 1, | ||||
|         color: '#fff', | ||||
|   backdrop: { | ||||
|     zIndex: theme.zIndex.drawer + 1, | ||||
|     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, | ||||
|         color: theme.palette.primary.contrastText, | ||||
|         width: '40px', | ||||
|         height: '40px', | ||||
|         '&:hover': { | ||||
|             backgroundColor: theme.palette.primary.main, | ||||
|             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, | ||||
|     }, | ||||
|     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 { | ||||
| 
 | ||||
|     constructor(props) { | ||||
|         super(props); | ||||
|         this.state = { | ||||
|             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 > | ||||
|         ); | ||||
|   constructor(props) { | ||||
|     super(props); | ||||
|     this.state = { | ||||
|       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="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 = { | ||||
|     arduino: PropTypes.string.isRequired, | ||||
|     name: PropTypes.string, | ||||
|     workspaceName: PropTypes.func.isRequired | ||||
|   arduino: PropTypes.string.isRequired, | ||||
|   name: PropTypes.string, | ||||
|   workspaceName: PropTypes.func.isRequired, | ||||
| }; | ||||
| 
 | ||||
| const mapStateToProps = state => ({ | ||||
|     arduino: state.workspace.code.arduino, | ||||
|     name: state.workspace.name | ||||
| const mapStateToProps = (state) => ({ | ||||
|   arduino: state.workspace.code.arduino, | ||||
|   name: state.workspace.name, | ||||
| }); | ||||
| 
 | ||||
| 
 | ||||
| export default connect(mapStateToProps, { workspaceName })(withStyles(styles, { withTheme: true })(CopyCode)); | ||||
| export default connect(mapStateToProps, { workspaceName })( | ||||
|   withStyles(styles, { withTheme: true })(CopyCode) | ||||
| ); | ||||
|  | ||||
| @ -1,16 +1,16 @@ | ||||
| import React, { Component } from 'react'; | ||||
| import PropTypes from 'prop-types'; | ||||
| import { connect } from 'react-redux'; | ||||
| import React, { Component } from "react"; | ||||
| import PropTypes from "prop-types"; | ||||
| 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 IconButton from '@material-ui/core/IconButton'; | ||||
| import Tooltip from '@material-ui/core/Tooltip'; | ||||
| import { withStyles } from "@material-ui/core/styles"; | ||||
| import IconButton from "@material-ui/core/IconButton"; | ||||
| import Tooltip from "@material-ui/core/Tooltip"; | ||||
| 
 | ||||
| import { faCamera } from "@fortawesome/free-solid-svg-icons"; | ||||
| import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||||
| @ -19,18 +19,16 @@ const styles = (theme) => ({ | ||||
|   button: { | ||||
|     backgroundColor: theme.palette.primary.main, | ||||
|     color: theme.palette.primary.contrastText, | ||||
|     width: '40px', | ||||
|     height: '40px', | ||||
|     '&:hover': { | ||||
|     width: "40px", | ||||
|     height: "40px", | ||||
|     "&:hover": { | ||||
|       backgroundColor: theme.palette.primary.main, | ||||
|       color: theme.palette.primary.contrastText, | ||||
|     } | ||||
|   } | ||||
|     }, | ||||
|   }, | ||||
| }); | ||||
| 
 | ||||
| 
 | ||||
| class Screenshot extends Component { | ||||
| 
 | ||||
|   getSvg = () => { | ||||
|     const workspace = Blockly.getMainWorkspace(); | ||||
|     var canvas = workspace.svgBlockCanvas_.cloneNode(true); | ||||
| @ -39,10 +37,12 @@ class Screenshot extends Component { | ||||
|       canvas.removeAttribute("transform"); | ||||
|       // does not work in  react
 | ||||
|       // var cssContent = Blockly.Css.CONTENT.join('');
 | ||||
|       var cssContent = ''; | ||||
|       for (var i = 0; i < document.getElementsByTagName('style').length; i++) { | ||||
|         if (/^blockly.*$/.test(document.getElementsByTagName('style')[i].id)) { | ||||
|           cssContent += document.getElementsByTagName('style')[i].firstChild.data.replace(/\..* \./g, '.'); | ||||
|       var cssContent = ""; | ||||
|       for (var i = 0; i < document.getElementsByTagName("style").length; i++) { | ||||
|         if (/^blockly.*$/.test(document.getElementsByTagName("style")[i].id)) { | ||||
|           cssContent += document | ||||
|             .getElementsByTagName("style") | ||||
|             [i].firstChild.data.replace(/\..* \./g, "."); | ||||
|         } | ||||
|       } | ||||
|       // ensure that fill-opacity is 1, because there cannot be a replacing
 | ||||
| @ -56,19 +56,24 @@ class Screenshot extends Component { | ||||
|       .blocklyPathLight { | ||||
|         display: flex; | ||||
|       }  `;
 | ||||
|       var css = '<defs><style type="text/css" xmlns="http://www.w3.org/1999/xhtml"><![CDATA[' + cssContent + ']]></style></defs>'; | ||||
|       var bbox = document.getElementsByClassName("blocklyBlockCanvas")[0].getBBox(); | ||||
|       var css = | ||||
|         '<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 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}"> | ||||
|                   ${css}">${content}</svg>`; | ||||
|       var fileName = detectWhitespacesAndReturnReadableResult(this.props.name); | ||||
|       // this.props.workspaceName(this.state.name);
 | ||||
|       fileName = `${fileName}.svg` | ||||
|       var blob = new Blob([xml], { type: 'image/svg+xml;base64' }); | ||||
|       fileName = `${fileName}.svg`; | ||||
|       var blob = new Blob([xml], { type: "image/svg+xml;base64" }); | ||||
|       saveAs(blob, fileName); | ||||
|     } | ||||
|   } | ||||
|   }; | ||||
| 
 | ||||
|   render() { | ||||
|     return ( | ||||
| @ -83,15 +88,18 @@ class Screenshot extends Component { | ||||
|         </Tooltip> | ||||
|       </div> | ||||
|     ); | ||||
|   }; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| Screenshot.propTypes = { | ||||
|   name: PropTypes.string.isRequired, | ||||
|   name: PropTypes.string, | ||||
| }; | ||||
| 
 | ||||
| const mapStateToProps = state => ({ | ||||
| const mapStateToProps = (state) => ({ | ||||
|   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