auto Save Blocks

This commit is contained in:
Mario Pesch 2022-01-14 08:12:20 +01:00
parent f388828c88
commit 748c29c260
4 changed files with 228 additions and 68 deletions

View File

@ -1,22 +1,93 @@
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 { IconButton } from "@material-ui/core";
import PropTypes from "prop-types";
import React from "react";
const SaveIcon = ({ loading }) => (
<Tooltip
title={"Auto save enabled"}
arrow
placement="right"
>
<div style={{ position: 'relative', width: "2rem", height: "2rem", margin: "1rem" }}>
{loading && <FontAwesomeIcon style={{ position: "absolute" }} icon={faCircleNotch} spin={true} size="2x" color="grey" />}
<FontAwesomeIcon style={{
const SaveIcon = ({ loading }) => {
const value = useSelector((state) => state.general.autoSave);
return (
<div>
{value === true ? (
<Tooltip title={"Auto save enabled"} arrow placement="right">
<IconButton
style={{
width: "40px",
height: "40px",
position: "absolute",
}}
>
{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 ? 'grey' : 'green'} size={loading ? "1x" : "lg"} />
</div>
</Tooltip>)
}}
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>
);
};
export default SaveIcon
SaveIcon.propTypes = {
setAutoSave: PropTypes.func.isRequired,
autoSave: PropTypes.bool.isRequired,
};
export default SaveIcon;

View File

@ -22,6 +22,7 @@ import { faCode } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import TooltipViewer from "./TooltipViewer";
import Dialog from "./Dialog";
import AutoSave from "./Workspace/AutoSave";
const styles = (theme) => ({
codeOn: {
@ -54,6 +55,7 @@ class Home extends Component {
key: "",
message: "",
open: true,
initialXml: sessionStorage.getItem("autoSaveXML"),
};
}
@ -114,11 +116,13 @@ class Home extends Component {
render() {
return (
<div>
<AutoSave />
{this.props.statistics ? (
<div style={{ float: "left", height: "40px", position: "relative" }}>
<WorkspaceStats />
</div>
) : null}
<div
className="workspaceFunc"
style={{ float: "right", height: "40px", marginBottom: "20px" }}
@ -161,6 +165,7 @@ class Home extends Component {
<FontAwesomeIcon icon={faCode} size="xs" />
</IconButton>
</Tooltip>
<TrashcanButtons />
<div className="blocklyWindow">
{this.props.project ? (
@ -169,7 +174,10 @@ class Home extends Component {
initialXml={this.props.project.xml}
/>
) : (
<BlocklyWindow blocklyCSS={{ height: "80vH" }} />
<BlocklyWindow
blocklyCSS={{ height: "80vH" }}
initialXml={this.state.initialXml}
/>
)}
</div>
</Grid>

View 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);

View File

@ -1,101 +1,110 @@
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 WorkspaceName from './WorkspaceName';
import SaveProject from './SaveProject';
import Compile from './Compile';
import SolutionCheck from '../Tutorial/SolutionCheck';
import DownloadProject from './DownloadProject';
import OpenProject from './OpenProject';
import Screenshot from './Screenshot';
import ShareProject from './ShareProject';
import ResetWorkspace from './ResetWorkspace';
import DeleteProject from './DeleteProject';
import CopyCode from './CopyCode';
import WorkspaceName from "./WorkspaceName";
import SaveProject from "./SaveProject";
import Compile from "./Compile";
import SolutionCheck from "../Tutorial/SolutionCheck";
import DownloadProject from "./DownloadProject";
import OpenProject from "./OpenProject";
import Screenshot from "./Screenshot";
import ShareProject from "./ShareProject";
import ResetWorkspace from "./ResetWorkspace";
import DeleteProject from "./DeleteProject";
import CopyCode from "./CopyCode";
class WorkspaceFunc extends Component {
componentDidUpdate() {
console.log(this.props.autosave);
}
render() {
return (
<div style={{ width: 'max-content', display: 'flex' }}>
{!this.props.assessment ?
<div style={{ width: "max-content", display: "flex" }}>
{!this.props.assessment ? (
<WorkspaceName
style={{ marginRight: '5px' }}
style={{ marginRight: "5px" }}
multiple={this.props.multiple}
project={this.props.project}
projectType={this.props.projectType}
/>
: null}
) : null}
{this.props.assessment ?
{this.props.assessment ? (
<SolutionCheck />
: !this.props.multiple ?
<Compile iconButton />
: null}
) : !this.props.multiple ? (
<Compile iconButton />
) : null}
{!this.props.multiple ?
<CopyCode iconButton />
: null}
{!this.props.multiple ? <CopyCode iconButton /> : null}
{this.props.user && !this.props.multiple ?
{this.props.user && !this.props.multiple ? (
<SaveProject
style={{ marginRight: '5px' }}
style={{ marginRight: "5px" }}
projectType={this.props.projectType}
project={this.props.project}
/>
: null}
) : null}
{!this.props.multiple ?
<DownloadProject style={{ marginRight: '5px' }} />
: null}
{!this.props.multiple ? (
<DownloadProject style={{ marginRight: "5px" }} />
) : null}
{!this.props.assessment && !this.props.multiple ?
{!this.props.assessment && !this.props.multiple ? (
<OpenProject
style={{ marginRight: '5px' }}
style={{ marginRight: "5px" }}
assessment={this.props.assessment}
/>
: null}
) : null}
{!this.props.assessment && !this.props.multiple ?
<Screenshot style={{ marginRight: '5px' }} />
: null}
{!this.props.assessment && !this.props.multiple ? (
<Screenshot style={{ marginRight: "5px" }} />
) : null}
{this.props.projectType !== 'gallery' && !this.props.assessment ?
{this.props.projectType !== "gallery" && !this.props.assessment ? (
<ShareProject
style={{ marginRight: '5px' }}
style={{ marginRight: "5px" }}
multiple={this.props.multiple}
project={this.props.project}
projectType={this.props.projectType}
/>
: null}
) : null}
{!this.props.multiple ?
<ResetWorkspace style={this.props.projectType === 'project' || this.props.projectType === 'gallery' ? { marginRight: '5px' } : null}
{!this.props.multiple ? (
<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
project={this.props.project}
projectType={this.props.projectType}
/>
: null}
) : null}
</div>
);
};
}
}
WorkspaceFunc.propTypes = {
user: PropTypes.object
user: PropTypes.object,
autosave: PropTypes.bool.isRequired,
};
const mapStateToProps = state => ({
user: state.auth.user
const mapStateToProps = (state) => ({
user: state.auth.user,
autosave: state.workspace.autosave,
});
export default connect(mapStateToProps, null)(WorkspaceFunc);