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