auto Save Blocks
This commit is contained in:
		
							parent
							
								
									f388828c88
								
							
						
					
					
						commit
						748c29c260
					
				| @ -1,22 +1,93 @@ | |||||||
| import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||||||
| import { faCircleNotch, faSave, faSpinner } from "@fortawesome/free-solid-svg-icons"; | import { useSelector } from "react-redux"; | ||||||
|  | import { | ||||||
|  |   faCircleNotch, | ||||||
|  |   faSave, | ||||||
|  |   faSpinner, | ||||||
|  | } from "@fortawesome/free-solid-svg-icons"; | ||||||
| import Tooltip from "@material-ui/core/Tooltip"; | import Tooltip from "@material-ui/core/Tooltip"; | ||||||
|  | import { IconButton } from "@material-ui/core"; | ||||||
|  | import PropTypes from "prop-types"; | ||||||
|  | import React from "react"; | ||||||
| 
 | 
 | ||||||
| const SaveIcon = ({ loading }) => ( | const SaveIcon = ({ loading }) => { | ||||||
|     <Tooltip |   const value = useSelector((state) => state.general.autoSave); | ||||||
|         title={"Auto save enabled"} | 
 | ||||||
|         arrow |   return ( | ||||||
|         placement="right" |     <div> | ||||||
|  |       {value === true ? ( | ||||||
|  |         <Tooltip title={"Auto save enabled"} arrow placement="right"> | ||||||
|  |           <IconButton | ||||||
|  |             style={{ | ||||||
|  |               width: "40px", | ||||||
|  |               height: "40px", | ||||||
|  |               position: "absolute", | ||||||
|  |             }} | ||||||
|           > |           > | ||||||
|         <div style={{ position: 'relative', width: "2rem", height: "2rem", margin: "1rem" }}> |             {loading && ( | ||||||
|             {loading && <FontAwesomeIcon style={{ position: "absolute" }} icon={faCircleNotch} spin={true} size="2x" color="grey" />} |               <FontAwesomeIcon | ||||||
|             <FontAwesomeIcon style={{ |                 style={{ position: "absolute" }} | ||||||
|  |                 icon={faCircleNotch} | ||||||
|  |                 spin={true} | ||||||
|  |                 size="2x" | ||||||
|  |                 color="#4EAF47" | ||||||
|  |               /> | ||||||
|  |             )} | ||||||
|  |             <FontAwesomeIcon | ||||||
|  |               style={{ | ||||||
|                 position: "absolute", |                 position: "absolute", | ||||||
|                 left: "50%", |                 left: "50%", | ||||||
|                 top: "50%", |                 top: "50%", | ||||||
|                 transform: "translate(-50%,-50%)", |                 transform: "translate(-50%,-50%)", | ||||||
|             }} icon={faSave} color={loading ? 'grey' : 'green'} size={loading ? "1x" : "lg"} /> |               }} | ||||||
|  |               icon={faSave} | ||||||
|  |               color={loading ? "gray" : "#4EAF47"} | ||||||
|  |               size={loading ? "1x" : "md"} | ||||||
|  |             /> | ||||||
|  |           </IconButton> | ||||||
|  |         </Tooltip> | ||||||
|  |       ) : ( | ||||||
|  |         <Tooltip title={"Auto save disabled"} arrow placement="right"> | ||||||
|  |           <IconButton | ||||||
|  |             style={{ | ||||||
|  |               width: "40px", | ||||||
|  |               height: "40px", | ||||||
|  |               position: "absolute", | ||||||
|  |             }} | ||||||
|  |             onClick={() => { | ||||||
|  |               this.propTypes.setAutoSave(true); | ||||||
|  |             }} | ||||||
|  |           > | ||||||
|  |             {loading && ( | ||||||
|  |               <FontAwesomeIcon | ||||||
|  |                 style={{ position: "absolute" }} | ||||||
|  |                 icon={faCircleNotch} | ||||||
|  |                 spin={true} | ||||||
|  |                 size="2x" | ||||||
|  |                 color="#4EAF47" | ||||||
|  |               /> | ||||||
|  |             )} | ||||||
|  |             <FontAwesomeIcon | ||||||
|  |               style={{ | ||||||
|  |                 position: "absolute", | ||||||
|  |                 left: "50%", | ||||||
|  |                 top: "50%", | ||||||
|  |                 transform: "translate(-50%,-50%)", | ||||||
|  |               }} | ||||||
|  |               icon={faSave} | ||||||
|  |               color={loading ? "gray" : "#4EAF47"} | ||||||
|  |               size={loading ? "1x" : "md"} | ||||||
|  |             /> | ||||||
|  |           </IconButton> | ||||||
|  |         </Tooltip> | ||||||
|  |       )} | ||||||
|     </div> |     </div> | ||||||
|     </Tooltip>) |   ); | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| export default SaveIcon | SaveIcon.propTypes = { | ||||||
|  |   setAutoSave: PropTypes.func.isRequired, | ||||||
|  |   autoSave: PropTypes.bool.isRequired, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default SaveIcon; | ||||||
|  | |||||||
| @ -22,6 +22,7 @@ import { faCode } from "@fortawesome/free-solid-svg-icons"; | |||||||
| import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||||||
| import TooltipViewer from "./TooltipViewer"; | import TooltipViewer from "./TooltipViewer"; | ||||||
| import Dialog from "./Dialog"; | import Dialog from "./Dialog"; | ||||||
|  | import AutoSave from "./Workspace/AutoSave"; | ||||||
| 
 | 
 | ||||||
| const styles = (theme) => ({ | const styles = (theme) => ({ | ||||||
|   codeOn: { |   codeOn: { | ||||||
| @ -54,6 +55,7 @@ class Home extends Component { | |||||||
|       key: "", |       key: "", | ||||||
|       message: "", |       message: "", | ||||||
|       open: true, |       open: true, | ||||||
|  |       initialXml: sessionStorage.getItem("autoSaveXML"), | ||||||
|     }; |     }; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @ -114,11 +116,13 @@ class Home extends Component { | |||||||
|   render() { |   render() { | ||||||
|     return ( |     return ( | ||||||
|       <div> |       <div> | ||||||
|  |         <AutoSave /> | ||||||
|         {this.props.statistics ? ( |         {this.props.statistics ? ( | ||||||
|           <div style={{ float: "left", height: "40px", position: "relative" }}> |           <div style={{ float: "left", height: "40px", position: "relative" }}> | ||||||
|             <WorkspaceStats /> |             <WorkspaceStats /> | ||||||
|           </div> |           </div> | ||||||
|         ) : null} |         ) : null} | ||||||
|  | 
 | ||||||
|         <div |         <div | ||||||
|           className="workspaceFunc" |           className="workspaceFunc" | ||||||
|           style={{ float: "right", height: "40px", marginBottom: "20px" }} |           style={{ float: "right", height: "40px", marginBottom: "20px" }} | ||||||
| @ -161,6 +165,7 @@ class Home extends Component { | |||||||
|                 <FontAwesomeIcon icon={faCode} size="xs" /> |                 <FontAwesomeIcon icon={faCode} size="xs" /> | ||||||
|               </IconButton> |               </IconButton> | ||||||
|             </Tooltip> |             </Tooltip> | ||||||
|  | 
 | ||||||
|             <TrashcanButtons /> |             <TrashcanButtons /> | ||||||
|             <div className="blocklyWindow"> |             <div className="blocklyWindow"> | ||||||
|               {this.props.project ? ( |               {this.props.project ? ( | ||||||
| @ -169,7 +174,10 @@ class Home extends Component { | |||||||
|                   initialXml={this.props.project.xml} |                   initialXml={this.props.project.xml} | ||||||
|                 /> |                 /> | ||||||
|               ) : ( |               ) : ( | ||||||
|                 <BlocklyWindow blocklyCSS={{ height: "80vH" }} /> |                 <BlocklyWindow | ||||||
|  |                   blocklyCSS={{ height: "80vH" }} | ||||||
|  |                   initialXml={this.state.initialXml} | ||||||
|  |                 /> | ||||||
|               )} |               )} | ||||||
|             </div> |             </div> | ||||||
|           </Grid> |           </Grid> | ||||||
|  | |||||||
							
								
								
									
										72
									
								
								src/components/Workspace/AutoSave.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/components/Workspace/AutoSave.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,72 @@ | |||||||
|  | import React, { Component } from "react"; | ||||||
|  | import PropTypes from "prop-types"; | ||||||
|  | import { connect } from "react-redux"; | ||||||
|  | import { workspaceName } from "../../actions/workspaceActions"; | ||||||
|  | import SaveIcon from "../CodeEditor/SaveIcon"; | ||||||
|  | 
 | ||||||
|  | const resetTimeout = (id, newID) => { | ||||||
|  |   clearTimeout(id); | ||||||
|  |   return newID; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | class AutoSave extends Component { | ||||||
|  |   constructor(props) { | ||||||
|  |     super(props); | ||||||
|  |     this.state = { | ||||||
|  |       timeout: null, | ||||||
|  |       value: "", | ||||||
|  |       saved: false, | ||||||
|  |       autosave: false, | ||||||
|  |     }; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   editValue = (value) => { | ||||||
|  |     this.setState({ | ||||||
|  |       timeout: resetTimeout( | ||||||
|  |         this.state.timeout, | ||||||
|  |         setTimeout(this.saveValue, 400) | ||||||
|  |       ), | ||||||
|  |       value: value, | ||||||
|  |     }); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   saveValue = () => { | ||||||
|  |     this.setState({ ...this.state, saved: true }); | ||||||
|  |     sessionStorage.setItem("autoSaveXML", this.props.xml); | ||||||
|  |     setTimeout(() => this.setState({ ...this.state, saved: false }), 1000); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   componentDidMount() { | ||||||
|  |     console.log(this.props.xml); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   componentDidUpdate(prevProps) { | ||||||
|  |     if (prevProps.xml !== this.props.xml) { | ||||||
|  |       this.editValue(this.props.xml); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   render() { | ||||||
|  |     return ( | ||||||
|  |       <div> | ||||||
|  |         <SaveIcon loading={this.state.saved} autosave={this.props.autosave} /> | ||||||
|  |       </div> | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | AutoSave.propTypes = { | ||||||
|  |   xml: PropTypes.string.isRequired, | ||||||
|  |   name: PropTypes.string, | ||||||
|  |   workspaceName: PropTypes.func.isRequired, | ||||||
|  |   setAutosave: PropTypes.func.isRequired, | ||||||
|  |   autosave: PropTypes.bool.isRequired, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const mapStateToProps = (state) => ({ | ||||||
|  |   auto: state.general.autosave, | ||||||
|  |   xml: state.workspace.code.xml, | ||||||
|  |   name: state.workspace.name, | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | export default connect(mapStateToProps, { workspaceName })(AutoSave); | ||||||
| @ -1,101 +1,110 @@ | |||||||
| import React, { Component } from 'react'; | import React, { Component } from "react"; | ||||||
| import PropTypes from 'prop-types'; | import PropTypes from "prop-types"; | ||||||
| import { connect } from 'react-redux'; | import { connect } from "react-redux"; | ||||||
| 
 | 
 | ||||||
| import WorkspaceName from './WorkspaceName'; | import WorkspaceName from "./WorkspaceName"; | ||||||
| import SaveProject from './SaveProject'; | import SaveProject from "./SaveProject"; | ||||||
| import Compile from './Compile'; | import Compile from "./Compile"; | ||||||
| import SolutionCheck from '../Tutorial/SolutionCheck'; | import SolutionCheck from "../Tutorial/SolutionCheck"; | ||||||
| import DownloadProject from './DownloadProject'; | import DownloadProject from "./DownloadProject"; | ||||||
| import OpenProject from './OpenProject'; | import OpenProject from "./OpenProject"; | ||||||
| import Screenshot from './Screenshot'; | import Screenshot from "./Screenshot"; | ||||||
| import ShareProject from './ShareProject'; | import ShareProject from "./ShareProject"; | ||||||
| import ResetWorkspace from './ResetWorkspace'; | import ResetWorkspace from "./ResetWorkspace"; | ||||||
| import DeleteProject from './DeleteProject'; | import DeleteProject from "./DeleteProject"; | ||||||
| import CopyCode from './CopyCode'; | import CopyCode from "./CopyCode"; | ||||||
| 
 | 
 | ||||||
| class WorkspaceFunc extends Component { | class WorkspaceFunc extends Component { | ||||||
|  |   componentDidUpdate() { | ||||||
|  |     console.log(this.props.autosave); | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   render() { |   render() { | ||||||
|     return ( |     return ( | ||||||
|       <div style={{ width: 'max-content', display: 'flex' }}> |       <div style={{ width: "max-content", display: "flex" }}> | ||||||
| 
 |         {!this.props.assessment ? ( | ||||||
|         {!this.props.assessment ? |  | ||||||
|           <WorkspaceName |           <WorkspaceName | ||||||
|             style={{ marginRight: '5px' }} |             style={{ marginRight: "5px" }} | ||||||
|             multiple={this.props.multiple} |             multiple={this.props.multiple} | ||||||
|             project={this.props.project} |             project={this.props.project} | ||||||
|             projectType={this.props.projectType} |             projectType={this.props.projectType} | ||||||
|           /> |           /> | ||||||
|           : null} |         ) : null} | ||||||
| 
 | 
 | ||||||
|         {this.props.assessment ? |         {this.props.assessment ? ( | ||||||
|           <SolutionCheck /> |           <SolutionCheck /> | ||||||
|           : !this.props.multiple ? |         ) : !this.props.multiple ? ( | ||||||
|           <Compile iconButton /> |           <Compile iconButton /> | ||||||
|             : null} |         ) : null} | ||||||
| 
 | 
 | ||||||
|         {!this.props.multiple ? |         {!this.props.multiple ? <CopyCode iconButton /> : null} | ||||||
|           <CopyCode iconButton /> |  | ||||||
|           : null} |  | ||||||
| 
 | 
 | ||||||
| 
 |         {this.props.user && !this.props.multiple ? ( | ||||||
|         {this.props.user && !this.props.multiple ? |  | ||||||
|           <SaveProject |           <SaveProject | ||||||
|             style={{ marginRight: '5px' }} |             style={{ marginRight: "5px" }} | ||||||
|             projectType={this.props.projectType} |             projectType={this.props.projectType} | ||||||
|             project={this.props.project} |             project={this.props.project} | ||||||
|           /> |           /> | ||||||
|           : null} |         ) : null} | ||||||
| 
 | 
 | ||||||
|         {!this.props.multiple ? |         {!this.props.multiple ? ( | ||||||
|           <DownloadProject style={{ marginRight: '5px' }} /> |           <DownloadProject style={{ marginRight: "5px" }} /> | ||||||
|           : null} |         ) : null} | ||||||
| 
 | 
 | ||||||
| 
 |         {!this.props.assessment && !this.props.multiple ? ( | ||||||
|         {!this.props.assessment && !this.props.multiple ? |  | ||||||
|           <OpenProject |           <OpenProject | ||||||
|             style={{ marginRight: '5px' }} |             style={{ marginRight: "5px" }} | ||||||
|             assessment={this.props.assessment} |             assessment={this.props.assessment} | ||||||
|           /> |           /> | ||||||
|           : null} |         ) : null} | ||||||
| 
 | 
 | ||||||
|         {!this.props.assessment && !this.props.multiple ? |         {!this.props.assessment && !this.props.multiple ? ( | ||||||
|           <Screenshot style={{ marginRight: '5px' }} /> |           <Screenshot style={{ marginRight: "5px" }} /> | ||||||
|           : null} |         ) : null} | ||||||
| 
 | 
 | ||||||
|         {this.props.projectType !== 'gallery' && !this.props.assessment ? |         {this.props.projectType !== "gallery" && !this.props.assessment ? ( | ||||||
|           <ShareProject |           <ShareProject | ||||||
|             style={{ marginRight: '5px' }} |             style={{ marginRight: "5px" }} | ||||||
|             multiple={this.props.multiple} |             multiple={this.props.multiple} | ||||||
|             project={this.props.project} |             project={this.props.project} | ||||||
|             projectType={this.props.projectType} |             projectType={this.props.projectType} | ||||||
|           /> |           /> | ||||||
|           : null} |         ) : null} | ||||||
| 
 | 
 | ||||||
|         {!this.props.multiple ? |         {!this.props.multiple ? ( | ||||||
|           <ResetWorkspace style={this.props.projectType === 'project' || this.props.projectType === 'gallery' ? { marginRight: '5px' } : null} |           <ResetWorkspace | ||||||
|  |             style={ | ||||||
|  |               this.props.projectType === "project" || | ||||||
|  |               this.props.projectType === "gallery" | ||||||
|  |                 ? { marginRight: "5px" } | ||||||
|  |                 : null | ||||||
|  |             } | ||||||
|           /> |           /> | ||||||
|           : null} |         ) : null} | ||||||
| 
 | 
 | ||||||
|         {!this.props.assessment && (this.props.projectType === 'project' || this.props.projectType === 'gallery') && this.props.user && this.props.user.email === this.props.project.creator ? |         {!this.props.assessment && | ||||||
|  |         (this.props.projectType === "project" || | ||||||
|  |           this.props.projectType === "gallery") && | ||||||
|  |         this.props.user && | ||||||
|  |         this.props.user.email === this.props.project.creator ? ( | ||||||
|           <DeleteProject |           <DeleteProject | ||||||
|             project={this.props.project} |             project={this.props.project} | ||||||
|             projectType={this.props.projectType} |             projectType={this.props.projectType} | ||||||
|           /> |           /> | ||||||
|           : null} |         ) : null} | ||||||
| 
 |  | ||||||
|       </div> |       </div> | ||||||
|     ); |     ); | ||||||
|   }; |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| WorkspaceFunc.propTypes = { | WorkspaceFunc.propTypes = { | ||||||
|   user: PropTypes.object |   user: PropTypes.object, | ||||||
|  |   autosave: PropTypes.bool.isRequired, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const mapStateToProps = state => ({ | const mapStateToProps = (state) => ({ | ||||||
|   user: state.auth.user |   user: state.auth.user, | ||||||
|  |   autosave: state.workspace.autosave, | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| export default connect(mapStateToProps, null)(WorkspaceFunc); | export default connect(mapStateToProps, null)(WorkspaceFunc); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user