Compare commits

..
Author SHA1 Message Date
felixerdy d20d8b9e97 add xml code changes 2021-09-16 16:51:10 +02:00
felixerdy 53b4f5dfeb keep workspace code and prepare dialog 2021-09-16 16:00:27 +02:00
7 changed files with 9551 additions and 10929 deletions
+110 -848
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -19,6 +19,7 @@
"@testing-library/user-event": "^7.2.1", "@testing-library/user-event": "^7.2.1",
"axios": "^0.21.0", "axios": "^0.21.0",
"blockly": "^6.20210701.0", "blockly": "^6.20210701.0",
"diff-js-xml": "^1.0.6",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"mnemonic-id": "^3.2.7", "mnemonic-id": "^3.2.7",
"moment": "^2.28.0", "moment": "^2.28.0",
@@ -34,8 +35,7 @@
"reactour": "^1.18.0", "reactour": "^1.18.0",
"redux": "^4.0.5", "redux": "^4.0.5",
"redux-thunk": "^2.3.0", "redux-thunk": "^2.3.0",
"rich-markdown-editor": "^11.17.7", "styled-components": "^4.4.1",
"styled-components": "^5.0.0",
"uuid": "^8.3.1" "uuid": "^8.3.1"
}, },
"scripts": { "scripts": {
+29 -25
View File
@@ -20,16 +20,18 @@ class BlocklyWindow extends Component {
componentDidMount() { componentDidMount() {
const workspace = Blockly.getMainWorkspace(); const workspace = Blockly.getMainWorkspace();
this.props.onChangeWorkspace({}); if (!this.props.readOnly) {
this.props.clearStats(); this.props.onChangeWorkspace({});
workspace.addChangeListener((event) => { this.props.clearStats();
this.props.onChangeWorkspace(event); workspace.addChangeListener((event) => {
// switch on that a block is displayed disabled or not depending on whether it is correctly connected this.props.onChangeWorkspace(event);
// for SVG display, a deactivated block in the display is undesirable // switch on that a block is displayed disabled or not depending on whether it is correctly connected
if (this.props.blockDisabled) { // for SVG display, a deactivated block in the display is undesirable
Blockly.Events.disableOrphans(event); if (this.props.blockDisabled) {
} Blockly.Events.disableOrphans(event);
}); }
});
}
Blockly.svgResize(workspace); Blockly.svgResize(workspace);
const zoomToFit = new ZoomToFitControl(workspace); const zoomToFit = new ZoomToFitControl(workspace);
zoomToFit.init(); zoomToFit.init();
@@ -37,21 +39,23 @@ class BlocklyWindow extends Component {
componentDidUpdate(props) { componentDidUpdate(props) {
const workspace = Blockly.getMainWorkspace(); const workspace = Blockly.getMainWorkspace();
var xml = this.props.initialXml; if (!this.props.readOnly) {
// if svg is true, then the update process is done in the BlocklySvg component var xml = this.props.initialXml;
if (props.initialXml !== xml && !this.props.svg) { // if svg is true, then the update process is done in the BlocklySvg component
// guarantees that the current xml-code (this.props.initialXml) is rendered if (props.initialXml !== xml && !this.props.svg) {
workspace.clear(); // guarantees that the current xml-code (this.props.initialXml) is rendered
if (!xml) xml = initialXml; workspace.clear();
Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), workspace); if (!xml) xml = initialXml;
} Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), workspace);
if (props.language !== this.props.language) { }
// change language if (props.language !== this.props.language) {
if (!xml) xml = initialXml; // change language
var xmlDom = Blockly.Xml.textToDom(xml); if (!xml) xml = initialXml;
Blockly.Xml.clearWorkspaceAndLoadFromXml(xmlDom, workspace); var xmlDom = Blockly.Xml.textToDom(xml);
// var toolbox = workspace.getToolbox(); Blockly.Xml.clearWorkspaceAndLoadFromXml(xmlDom, workspace);
// workspace.updateToolbox(toolbox.toolboxDef_); // var toolbox = workspace.getToolbox();
// workspace.updateToolbox(toolbox.toolboxDef_);
}
} }
Blockly.svgResize(workspace); Blockly.svgResize(workspace);
} }
+103 -127
View File
@@ -1,124 +1,98 @@
import React, { Component } from "react"; import React, { Component } from 'react';
import Breadcrumbs from "./Breadcrumbs"; import Breadcrumbs from './Breadcrumbs';
import { withRouter } from "react-router-dom"; import { withRouter } from 'react-router-dom';
import Button from "@material-ui/core/Button"; import Button from '@material-ui/core/Button';
import Typography from "@material-ui/core/Typography"; import Typography from '@material-ui/core/Typography';
import * as Blockly from "blockly"; import * as Blockly from 'blockly'
import ReactMarkdown from "react-markdown"; import ReactMarkdown from 'react-markdown';
import Container from "@material-ui/core/Container"; import Container from '@material-ui/core/Container';
import ExpansionPanel from "@material-ui/core/ExpansionPanel"; import ExpansionPanel from '@material-ui/core/ExpansionPanel';
import ExpansionPanelSummary from "@material-ui/core/ExpansionPanelSummary"; import ExpansionPanelSummary from '@material-ui/core/ExpansionPanelSummary';
import ExpansionPanelDetails from "@material-ui/core/ExpansionPanelDetails"; import ExpansionPanelDetails from '@material-ui/core/ExpansionPanelDetails';
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faChevronDown } from "@fortawesome/free-solid-svg-icons"; import { faChevronDown } from "@fortawesome/free-solid-svg-icons";
import { FaqQuestions } from "../data/faq"; import { FaqQuestions } from '../data/faq'
import Editor from "rich-markdown-editor";
class Faq extends Component { class Faq extends Component {
state = {
panel: "",
expanded: false,
text: "",
};
handleChange = (panel) => { state = {
this.setState({ panel: this.state.panel === panel ? "" : panel }); panel: '',
}; expanded: false
}
componentDidMount() {
// Ensure that Blockly.setLocale is adopted in the component.
// Otherwise, the text will not be displayed until the next update of the component.
window.scrollTo(0, 0); handleChange = (panel) => {
this.forceUpdate(); this.setState({ panel: this.state.panel === panel ? '' : panel });
} };
render() { componentDidMount() {
const { panel } = this.state; // Ensure that Blockly.setLocale is adopted in the component.
return ( // Otherwise, the text will not be displayed until the next update of the component.
<div>
<Breadcrumbs window.scrollTo(0, 0)
content={[{ link: this.props.location.pathname, title: "FAQ" }]} this.forceUpdate();
/> }
<Container fixed>
<div style={{ margin: "0px 24px 0px 24px" }}> render() {
<h1>FAQ</h1> const { panel } = this.state;
{FaqQuestions().map((object, i) => { return (
return ( <div>
<ExpansionPanel <Breadcrumbs content={[{ link: this.props.location.pathname, title: 'FAQ' }]} />
expanded={panel === `panel${i}`} <Container fixed>
onChange={() => this.handleChange(`panel${i}`)} <div style={{ margin: '0px 24px 0px 24px' }}>
> <h1>FAQ</h1>
<ExpansionPanelSummary {FaqQuestions().map((object, i) => {
expandIcon={<FontAwesomeIcon icon={faChevronDown} />} return (
> <ExpansionPanel expanded={panel === `panel${i}`} onChange={() => this.handleChange(`panel${i}`)}>
<Typography variant="h6">{object.question}</Typography> <ExpansionPanelSummary
</ExpansionPanelSummary> expandIcon={
<ExpansionPanelDetails> <FontAwesomeIcon icon={faChevronDown} />
<Typography> }
<ReactMarkdown >
className="news" <Typography variant="h6">{object.question}</Typography>
allowDangerousHtml="true" </ExpansionPanelSummary>
children={object.answer} <ExpansionPanelDetails>
></ReactMarkdown> <Typography>
</Typography> <ReactMarkdown className="news" allowDangerousHtml="true" children={object.answer}>
</ExpansionPanelDetails> </ReactMarkdown>
</ExpansionPanel> </Typography>
); </ExpansionPanelDetails>
})} </ExpansionPanel>
{this.props.button ? ( )
<Button })}
style={{ marginTop: "20px" }} {
variant="contained" this.props.button ?
color="primary" <Button
onClick={() => { style={{ marginTop: '20px' }}
this.props.history.push(this.props.button.link); variant="contained"
}} color="primary"
> onClick={() => { this.props.history.push(this.props.button.link) }}
{this.props.button.title} >
</Button> {this.props.button.title}
) : ( </Button>
<Button :
style={{ marginTop: "20px" }} <Button
variant="contained" style={{ marginTop: '20px' }}
color="primary" variant="contained"
onClick={() => { color="primary"
this.props.history.push("/"); onClick={() => { this.props.history.push('/') }}
}} >
> {Blockly.Msg.button_back}
{Blockly.Msg.button_back} </Button>
</Button> }
)} </div>
<Editor </Container>
defaultValue="Hello world!" </div >
// value={this.state.text} );
onChange={(e) => { };
this.setState({ text: e() });
}}
uploadImage={async (file) => {}}
/>
<Button
style={{ marginTop: "20px" }}
variant="contained"
color="primary"
onClick={() => {
console.log(this.state.text);
}}
>
{Blockly.Msg.button_back}
</Button>
</div>
</Container>
</div>
);
}
} }
export default withRouter(Faq); export default withRouter(Faq);
/* /*
<ExpansionPanel expanded={panel === 'panel1'} onChange={() => this.handleChange('panel1')}> <ExpansionPanel expanded={panel === 'panel1'} onChange={() => this.handleChange('panel1')}>
<ExpansionPanelSummary <ExpansionPanelSummary
expandIcon={ expandIcon={
@@ -181,23 +155,25 @@ vitae egestas augue. Duis vel est augue.
</ExpansionPanel> </ExpansionPanel>
*/ */
// {{ // {{
// this.props.button ? // this.props.button ?
// <Button // <Button
// style={{ marginTop: '20px' }} // style={{ marginTop: '20px' }}
// variant="contained" // variant="contained"
// color="primary" // color="primary"
// onClick={() => { this.props.history.push(this.props.button.link) }} // onClick={() => { this.props.history.push(this.props.button.link) }}
// > // >
// {this.props.button.title} // {this.props.button.title}
// </Button> // </Button>
// : // :
// <Button // <Button
// style={{ marginTop: '20px' }} // style={{ marginTop: '20px' }}
// variant="contained" // variant="contained"
// color="primary" // color="primary"
// onClick={() => { this.props.history.push('/') }} // onClick={() => { this.props.history.push('/') }}
// > // >
// {Blockly.Msg.button_back} // {Blockly.Msg.button_back}
// </Button> // </Button>
// }} // }}
+14 -6
View File
@@ -77,7 +77,7 @@ class Home extends Component {
componentWillUnmount() { componentWillUnmount() {
this.props.clearStats(); this.props.clearStats();
this.props.workspaceName(null); // this.props.workspaceName(null);
} }
onChange = () => { onChange = () => {
@@ -112,10 +112,17 @@ class Home extends Component {
</Tooltip> </Tooltip>
<TrashcanButtons /> <TrashcanButtons />
<div className='blocklyWindow'> <div className='blocklyWindow'>
{this.props.project ? {this.props.project ? (
< BlocklyWindow blocklyCSS={{ height: '80vH' }} initialXml={this.props.project.xml} /> <BlocklyWindow
: < BlocklyWindow blocklyCSS={{ height: '80vH' }} /> blocklyCSS={{ height: "80vH" }}
} initialXml={this.props.project.xml}
/>
) : (
<BlocklyWindow
blocklyCSS={{ height: "80vH" }}
initialXml={this.props.workspaceCode?.xml}
/>
)}
</div> </div>
</Grid> </Grid>
{this.state.codeOn ? {this.state.codeOn ?
@@ -146,7 +153,8 @@ Home.propTypes = {
const mapStateToProps = state => ({ const mapStateToProps = state => ({
message: state.message, message: state.message,
statistics: state.general.statistics statistics: state.general.statistics,
workspaceCode: state.workspace.code
}); });
+67 -5
View File
@@ -18,6 +18,11 @@ import Divider from "@material-ui/core/Divider";
import Typography from "@material-ui/core/Typography"; import Typography from "@material-ui/core/Typography";
import Backdrop from "@material-ui/core/Backdrop"; import Backdrop from "@material-ui/core/Backdrop";
import CircularProgress from "@material-ui/core/CircularProgress"; import CircularProgress from "@material-ui/core/CircularProgress";
import Dialog from "../Dialog";
import Button from "@material-ui/core/Button";
import { initialXml } from "../Blockly/initialXml";
import {diffAsXml} from 'diff-js-xml';
const styles = (theme) => ({ const styles = (theme) => ({
link: { link: {
@@ -36,6 +41,7 @@ class ProjectHome extends Component {
type: "", type: "",
key: "", key: "",
message: "", message: "",
dialog: false,
}; };
componentDidMount() { componentDidMount() {
@@ -126,10 +132,43 @@ class ProjectHome extends Component {
overflow: "hidden", overflow: "hidden",
}} }}
> >
<Link <div
to={`/${ onClick={async () => {
data === "Projekte" ? "project" : "gallery" const isCodeDifferent = new Promise((resolve) => {
}/${project._id}`} // resolve successfully when there is no existing workspace XML code
if(!this.props.workspaceCode.xml) {
resolve(false)
return
}
// get difference of XML
// TODO: check if code of project is different to workspace code
diffAsXml(
this.props.workspaceCode.xml,
initialXml,
undefined,
undefined,
(result) => {
resolve(result.length !== 0);
}
)
}
);
const showDialog = await isCodeDifferent;
if (showDialog)
this.setState({
dialog: true,
});
else {
this.props.history.push(
`/${
data === "Projekte" ? "project" : "gallery"
}/${project._id}`
);
}
}}
style={{ textDecoration: "none", color: "inherit" }} style={{ textDecoration: "none", color: "inherit" }}
> >
<h3 style={{ marginTop: 0 }}>{project.title}</h3> <h3 style={{ marginTop: 0 }}>{project.title}</h3>
@@ -139,6 +178,7 @@ class ProjectHome extends Component {
<BlocklyWindow <BlocklyWindow
svg svg
blockDisabled blockDisabled
readOnly
initialXml={project.xml} initialXml={project.xml}
/> />
<Typography <Typography
@@ -151,7 +191,7 @@ class ProjectHome extends Component {
> >
{project.description} {project.description}
</Typography> </Typography>
</Link> </div>
{this.props.user && {this.props.user &&
this.props.user.email === project.creator ? ( this.props.user.email === project.creator ? (
<div> <div>
@@ -206,6 +246,27 @@ class ProjectHome extends Component {
type={this.state.type} type={this.state.type}
key={this.state.key} key={this.state.key}
/> />
<Dialog
open={this.state.dialog}
title="Achtung"
actions={
<React.Fragment>
<Button
onClick={() => {
this.setState({ dialog: false });
// TODO: navigate to project
}}
>
Verwerfen
</Button>
<Button onClick={() => {}} color="primary">
Speichern
</Button>
</React.Fragment>
}
>
Möchtest du deinen bisherigen Code als Projekt speichern?
</Dialog>
</div> </div>
); );
} }
@@ -226,6 +287,7 @@ const mapStateToProps = (state) => ({
progress: state.project.progress, progress: state.project.progress,
user: state.auth.user, user: state.auth.user,
message: state.message, message: state.message,
workspaceCode: state.workspace.code,
}); });
export default connect(mapStateToProps, { export default connect(mapStateToProps, {
+9226 -9916
View File
File diff suppressed because it is too large Load Diff