create and display content to share
This commit is contained in:
		
							parent
							
								
									d0dda4038e
								
							
						
					
					
						commit
						6db8c094ea
					
				| @ -5,6 +5,8 @@ import { clearStats, workspaceName } from '../actions/workspaceActions'; | |||||||
| 
 | 
 | ||||||
| import * as Blockly from 'blockly/core'; | import * as Blockly from 'blockly/core'; | ||||||
| 
 | 
 | ||||||
|  | import axios from 'axios'; | ||||||
|  | 
 | ||||||
| import WorkspaceStats from './WorkspaceStats'; | import WorkspaceStats from './WorkspaceStats'; | ||||||
| import WorkspaceFunc from './WorkspaceFunc'; | import WorkspaceFunc from './WorkspaceFunc'; | ||||||
| import BlocklyWindow from './Blockly/BlocklyWindow'; | import BlocklyWindow from './Blockly/BlocklyWindow'; | ||||||
| @ -17,6 +19,8 @@ import Grid from '@material-ui/core/Grid'; | |||||||
| 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 { withStyles } from '@material-ui/core/styles'; | import { withStyles } from '@material-ui/core/styles'; | ||||||
|  | import Backdrop from '@material-ui/core/Backdrop'; | ||||||
|  | import CircularProgress from '@material-ui/core/CircularProgress'; | ||||||
| 
 | 
 | ||||||
| import { faCode } from "@fortawesome/free-solid-svg-icons"; | import { faCode } from "@fortawesome/free-solid-svg-icons"; | ||||||
| import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||||||
| @ -50,17 +54,28 @@ class Home extends Component { | |||||||
|     gallery: [], |     gallery: [], | ||||||
|     share: [], |     share: [], | ||||||
|     projectToLoad: undefined, |     projectToLoad: undefined, | ||||||
|  |     progress: false, | ||||||
|     stats: window.localStorage.getItem('stats'), |     stats: window.localStorage.getItem('stats'), | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   componentDidMount() { |   componentDidMount() { | ||||||
|     this.setState({ stats: window.localStorage.getItem('stats') }) |     this.setState({ stats: window.localStorage.getItem('stats') }) | ||||||
|     this.props.workspaceName(createNameId()); |     if(this.props.match.params.shareId || this.props.match.params.galleryId){ | ||||||
|     fetch(process.env.REACT_APP_BLOCKLY_API + this.props.location.pathname) |       this.setState({progress: true}); | ||||||
|       .then(res => res.json()) |       axios.get(`${process.env.REACT_APP_BLOCKLY_API}${this.props.location.pathname}`) | ||||||
|       .then((data) => { |         .then(res => { | ||||||
|         this.setState({ projectToLoad: data }) |           var shareContent = res.data.content; | ||||||
|  |           this.props.workspaceName(res.data.content.name); | ||||||
|  |           this.setState({ projectToLoad: res.data.content, progress: false }); | ||||||
|         }) |         }) | ||||||
|  |         .catch(err => { | ||||||
|  |           this.setState({ progress: false, snackbar: true, key: Date.now(), message: `Fehler beim Erstellen eines Links zum Teilen deines Programmes. Versuche es noch einmal.`, type: 'error' }); | ||||||
|  |           window.scrollTo(0, 0); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |       this.props.workspaceName(createNameId()); | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -90,6 +105,12 @@ class Home extends Component { | |||||||
| 
 | 
 | ||||||
|   render() { |   render() { | ||||||
|     return ( |     return ( | ||||||
|  |       <div> | ||||||
|  |         {this.state.progress ? | ||||||
|  |           <Backdrop open invisible> | ||||||
|  |             <CircularProgress color="primary" /> | ||||||
|  |           </Backdrop> | ||||||
|  |          : | ||||||
|           <div> |           <div> | ||||||
|           {this.state.stats ? |           {this.state.stats ? | ||||||
|             <div style={{ float: 'left', height: '40px', position: 'relative' }}><WorkspaceStats /></div> |             <div style={{ float: 'left', height: '40px', position: 'relative' }}><WorkspaceStats /></div> | ||||||
| @ -109,7 +130,8 @@ class Home extends Component { | |||||||
|               </Tooltip> |               </Tooltip> | ||||||
|               <TrashcanButtons /> |               <TrashcanButtons /> | ||||||
|               {this.state.projectToLoad ? |               {this.state.projectToLoad ? | ||||||
|               < BlocklyWindow blocklyCSS={{ height: '80vH' }} initialXml={this.state.projectToLoad.xml} /> : < BlocklyWindow blocklyCSS={{ height: '80vH' }} /> |                 < BlocklyWindow blocklyCSS={{ height: '80vH' }} initialXml={this.state.projectToLoad.xml} /> | ||||||
|  |               : < BlocklyWindow blocklyCSS={{ height: '80vH' }} /> | ||||||
|               } |               } | ||||||
| 
 | 
 | ||||||
|             </Grid> |             </Grid> | ||||||
| @ -121,6 +143,8 @@ class Home extends Component { | |||||||
|           </Grid> |           </Grid> | ||||||
|           <HintTutorialExists /> |           <HintTutorialExists /> | ||||||
|         </div> |         </div> | ||||||
|  |       } | ||||||
|  |       </div> | ||||||
|     ); |     ); | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  | |||||||
| @ -5,7 +5,9 @@ import { clearStats, onChangeCode, workspaceName } from '../actions/workspaceAct | |||||||
| 
 | 
 | ||||||
| import * as Blockly from 'blockly/core'; | import * as Blockly from 'blockly/core'; | ||||||
| 
 | 
 | ||||||
|  | import axios from 'axios'; | ||||||
| import { saveAs } from 'file-saver'; | import { saveAs } from 'file-saver'; | ||||||
|  | import { createId } from 'mnemonic-id'; | ||||||
| 
 | 
 | ||||||
| import { detectWhitespacesAndReturnReadableResult } from '../helpers/whitespace'; | import { detectWhitespacesAndReturnReadableResult } from '../helpers/whitespace'; | ||||||
| import { initialXml } from './Blockly/initialXml.js'; | import { initialXml } from './Blockly/initialXml.js'; | ||||||
| @ -14,6 +16,8 @@ import Compile from './Compile'; | |||||||
| import SolutionCheck from './Tutorial/SolutionCheck'; | import SolutionCheck from './Tutorial/SolutionCheck'; | ||||||
| import Snackbar from './Snackbar'; | import Snackbar from './Snackbar'; | ||||||
| 
 | 
 | ||||||
|  | import { Link } from 'react-router-dom'; | ||||||
|  | 
 | ||||||
| import withWidth, { isWidthDown } from '@material-ui/core/withWidth'; | import withWidth, { isWidthDown } from '@material-ui/core/withWidth'; | ||||||
| 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'; | ||||||
| @ -21,7 +25,6 @@ import IconButton from '@material-ui/core/IconButton'; | |||||||
| import Tooltip from '@material-ui/core/Tooltip'; | import Tooltip from '@material-ui/core/Tooltip'; | ||||||
| import TextField from '@material-ui/core/TextField'; | import TextField from '@material-ui/core/TextField'; | ||||||
| import Typography from '@material-ui/core/Typography'; | import Typography from '@material-ui/core/Typography'; | ||||||
| import { createId } from 'mnemonic-id'; |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| import Dialog from './Dialog'; | import Dialog from './Dialog'; | ||||||
| @ -33,7 +36,7 @@ import DialogTitle from '@material-ui/core/DialogTitle'; | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| import { faPen, faSave, faUpload, faCamera, faShare, faShareAlt } from "@fortawesome/free-solid-svg-icons"; | import { faPen, faSave, faUpload, faCamera, faShare, faShareAlt, faCopy } from "@fortawesome/free-solid-svg-icons"; | ||||||
| import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||||||
| 
 | 
 | ||||||
| const styles = (theme) => ({ | const styles = (theme) => ({ | ||||||
| @ -55,6 +58,14 @@ const styles = (theme) => ({ | |||||||
|     '&:hover': { |     '&:hover': { | ||||||
|       color: theme.palette.primary.main, |       color: theme.palette.primary.main, | ||||||
|     } |     } | ||||||
|  |   }, | ||||||
|  |   link: { | ||||||
|  |     color: theme.palette.primary.main, | ||||||
|  |     textDecoration: 'none', | ||||||
|  |     '&:hover': { | ||||||
|  |       color: theme.palette.primary.main, | ||||||
|  |       textDecoration: 'underline' | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| @ -74,14 +85,13 @@ class WorkspaceFunc extends Component { | |||||||
|       share: false, |       share: false, | ||||||
|       name: props.name, |       name: props.name, | ||||||
|       snackbar: false, |       snackbar: false, | ||||||
|  |       type: '', | ||||||
|       key: '', |       key: '', | ||||||
|       message: '', |       message: '', | ||||||
|       id: '' |       id: '' | ||||||
|     }; |     }; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|   componentDidUpdate(props) { |   componentDidUpdate(props) { | ||||||
|     if (props.name !== this.props.name) { |     if (props.name !== this.props.name) { | ||||||
|       this.setState({ name: this.props.name }); |       this.setState({ name: this.props.name }); | ||||||
| @ -89,7 +99,7 @@ class WorkspaceFunc extends Component { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   toggleDialog = () => { |   toggleDialog = () => { | ||||||
|     this.setState({ open: !this.state, share: false }); |     this.setState({ open: !this.state, share: false, file: false, saveFile: false, title: '', content: '' }); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   saveXmlFile = () => { |   saveXmlFile = () => { | ||||||
| @ -103,38 +113,20 @@ class WorkspaceFunc extends Component { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   shareBlocks = () => { |   shareBlocks = () => { | ||||||
|     let code = this.props.xml; |     var body = { | ||||||
|     let requestOptions = ''; |       _id: createId(10), | ||||||
|     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, |       name: this.state.name, | ||||||
|           xml: code |       xml: this.props.xml | ||||||
|         }) |  | ||||||
|     }; |     }; | ||||||
|       fetch(process.env.REACT_APP_BLOCKLY_API + '/share' + this.state.id, requestOptions) |     axios.post(`${process.env.REACT_APP_BLOCKLY_API}/share`, body) | ||||||
|         .then(response => response.json()) |       .then(res => { | ||||||
|         .then(data => this.setState({ share: true })); |         var shareContent = res.data.content; | ||||||
|     } |         this.setState({ share: true, open: true, title: 'Programm teilen', id: shareContent._id }); | ||||||
|     else { |  | ||||||
|       id = createId(10); |  | ||||||
|       requestOptions = { |  | ||||||
|         method: 'POST', |  | ||||||
|         headers: { 'Content-Type': 'application/json' }, |  | ||||||
|         body: JSON.stringify({ |  | ||||||
|           id: id, |  | ||||||
|           name: this.state.name, |  | ||||||
|           xml: code |  | ||||||
|       }) |       }) | ||||||
|       }; |       .catch(err => { | ||||||
|       fetch(process.env.REACT_APP_BLOCKLY_API + '/share', requestOptions) |         this.setState({ snackbar: true, key: Date.now(), message: `Fehler beim Erstellen eines Links zum Teilen deines Programmes. Versuche es noch einmal.`, type: 'error' }); | ||||||
|         .then(response => response.json()) |         window.scrollTo(0, 0); | ||||||
|         .then(data => this.setState({ id: data.id, share: true })); |       }); | ||||||
|     } |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   getSvg = () => { |   getSvg = () => { | ||||||
| @ -220,7 +212,7 @@ class WorkspaceFunc extends Component { | |||||||
|               var extensionPosition = xmlFile.name.lastIndexOf('.'); |               var extensionPosition = xmlFile.name.lastIndexOf('.'); | ||||||
|               this.props.workspaceName(xmlFile.name.substr(0, extensionPosition)); |               this.props.workspaceName(xmlFile.name.substr(0, extensionPosition)); | ||||||
|             } |             } | ||||||
|             this.setState({ snackbar: true, key: Date.now(), message: 'Das Projekt aus gegebener XML-Datei wurde erfolgreich eingefügt.' }); |             this.setState({ snackbar: true, type: 'success', key: Date.now(), message: 'Das Projekt aus gegebener XML-Datei wurde erfolgreich eingefügt.' }); | ||||||
|           } |           } | ||||||
|         } catch (err) { |         } catch (err) { | ||||||
|           this.setState({ open: true, file: false, title: 'Ungültige XML', content: 'Die XML-Datei konnte nicht in Blöcke zerlegt werden. Bitte überprüfe den XML-Code und versuche es erneut.' }); |           this.setState({ open: true, file: false, title: 'Ungültige XML', content: 'Die XML-Datei konnte nicht in Blöcke zerlegt werden. Bitte überprüfe den XML-Code und versuche es erneut.' }); | ||||||
| @ -232,7 +224,7 @@ class WorkspaceFunc extends Component { | |||||||
|   renameWorkspace = () => { |   renameWorkspace = () => { | ||||||
|     this.props.workspaceName(this.state.name); |     this.props.workspaceName(this.state.name); | ||||||
|     this.toggleDialog(); |     this.toggleDialog(); | ||||||
|     this.setState({ snackbar: true, key: Date.now(), message: `Das Projekt wurde erfolgreich in '${this.state.name}' umbenannt.` }); |     this.setState({ snackbar: true, type: 'success', key: Date.now(), message: `Das Projekt wurde erfolgreich in '${this.state.name}' umbenannt.` }); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   resetWorkspace = () => { |   resetWorkspace = () => { | ||||||
| @ -248,7 +240,7 @@ class WorkspaceFunc extends Component { | |||||||
|     if (!this.props.solutionCheck) { |     if (!this.props.solutionCheck) { | ||||||
|       this.props.workspaceName(null); |       this.props.workspaceName(null); | ||||||
|     } |     } | ||||||
|     this.setState({ snackbar: true, key: Date.now(), message: 'Das Projekt wurde erfolgreich zurückgesetzt.' }); |     this.setState({ snackbar: true, type: 'success', key: Date.now(), message: 'Das Projekt wurde erfolgreich zurückgesetzt.' }); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -320,29 +312,6 @@ class WorkspaceFunc extends Component { | |||||||
|           </IconButton> |           </IconButton> | ||||||
|         </Tooltip> |         </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={window.location.origin + "/share/" + this.state.id} |  | ||||||
|               label="url" |  | ||||||
|               type="email" |  | ||||||
|               fullWidth |  | ||||||
|             /> |  | ||||||
|           </DialogContent> |  | ||||||
|           <DialogActions> |  | ||||||
|             <Button onClick={this.toggleDialog} color="primary"> |  | ||||||
|               Cancel |  | ||||||
|           </Button> |  | ||||||
|           </DialogActions> |  | ||||||
|         </Dialog> |  | ||||||
| 
 |  | ||||||
|         <Dialog |         <Dialog | ||||||
|           open={this.state.open} |           open={this.state.open} | ||||||
|           title={this.state.title} |           title={this.state.title} | ||||||
| @ -356,13 +325,28 @@ class WorkspaceFunc extends Component { | |||||||
|               <TextField autoFocus placeholder={this.state.saveXml ? 'Dateiname' : 'Projektname'} value={this.state.name} onChange={this.setFileName} style={{ marginRight: '10px' }} /> |               <TextField autoFocus placeholder={this.state.saveXml ? 'Dateiname' : 'Projektname'} value={this.state.name} onChange={this.setFileName} style={{ marginRight: '10px' }} /> | ||||||
|               <Button disabled={!this.state.name} variant='contained' color='primary' onClick={() => { this.state.saveFile ? this.state.file === 'xml' ? this.saveXmlFile() : this.getSvg() : this.renameWorkspace(); this.toggleDialog(); }}>Eingabe</Button> |               <Button disabled={!this.state.name} variant='contained' color='primary' onClick={() => { this.state.saveFile ? this.state.file === 'xml' ? this.saveXmlFile() : this.getSvg() : this.renameWorkspace(); this.toggleDialog(); }}>Eingabe</Button> | ||||||
|             </div> |             </div> | ||||||
|  |           : this.state.share ? | ||||||
|  |             <div style={{ marginTop: '10px' }}> | ||||||
|  |               <Typography>Über den folgenden Link kannst du dein Programm teilen:</Typography> | ||||||
|  |               <Link to={`/share/${this.state.id}`} className={this.props.classes.link}>{`${window.location.origin}/share/${this.state.id}`}</Link> | ||||||
|  |               <Tooltip title='Link kopieren' arrow style={{ marginRight: '5px' }}> | ||||||
|  |                 <IconButton | ||||||
|  |                   onClick={() => { | ||||||
|  |                     navigator.clipboard.writeText(`${window.location.origin}/share/${this.state.id}`); | ||||||
|  |                     this.setState({ snackbar: true, key: Date.now(), message: 'Link erfolgreich in Zwischenablage gespeichert.', type: 'success' }); | ||||||
|  |                   }} | ||||||
|  |                 > | ||||||
|  |                   <FontAwesomeIcon icon={faCopy} size="xs" /> | ||||||
|  |                 </IconButton> | ||||||
|  |               </Tooltip> | ||||||
|  |             </div> | ||||||
|           : null} |           : null} | ||||||
|         </Dialog> |         </Dialog> | ||||||
| 
 | 
 | ||||||
|         <Snackbar |         <Snackbar | ||||||
|           open={this.state.snackbar} |           open={this.state.snackbar} | ||||||
|           message={this.state.message} |           message={this.state.message} | ||||||
|           type='success' |           type={this.state.type} | ||||||
|           key={this.state.key} |           key={this.state.key} | ||||||
|         /> |         /> | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user