-
-
- : null}
+ : null}
)
})}
- :
-
Es sind aktuell keine Projekte vorhanden.
- {this.props.location.pathname.replace('/','') === 'project' ?
+ :
+ Es sind aktuell keine Projekte vorhanden.
+ {this.props.location.pathname.replace('/', '') === 'project' ?
Erstelle jetzt dein eigenes Projekt oder lasse dich von Projektbeispielen in der Galerie inspirieren.
- : null}
+ : null}
}
diff --git a/src/components/Settings/LanguageSelector.js b/src/components/Settings/LanguageSelector.js
index dea7465..f069b1b 100644
--- a/src/components/Settings/LanguageSelector.js
+++ b/src/components/Settings/LanguageSelector.js
@@ -1,43 +1,58 @@
-import React from 'react';
-import { makeStyles } from '@material-ui/core/styles';
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import { connect } from 'react-redux';
+import { setLanguage } from '../../actions/generalActions';
+
+import * as Blockly from 'blockly/core';
+
import InputLabel from '@material-ui/core/InputLabel';
import MenuItem from '@material-ui/core/MenuItem';
import FormControl from '@material-ui/core/FormControl';
import Select from '@material-ui/core/Select';
+import Typography from '@material-ui/core/Typography';
+import FormHelperText from '@material-ui/core/FormHelperText';
-const useStyles = makeStyles((theme) => ({
- formControl: {
- margin: theme.spacing(1),
- minWidth: 120,
- },
- selectEmpty: {
- marginTop: theme.spacing(2),
- },
-}));
+class LanguageSelector extends Component {
-export default function LanguageSelector() {
- const classes = useStyles();
- const [lang, setLang] = React.useState(window.localStorage.getItem('locale'));
+ componentDidMount(){
+ // Ensure that Blockly.setLocale is adopted in the component.
+ // Otherwise, the text will not be displayed until the next update of the component.
+ this.forceUpdate();
+ }
- const handleChange = (event) => {
- setLang(event.target.value);
- window.localStorage.setItem('locale', event.target.value);
- };
+ handleChange = (event) => {
+ this.props.setLanguage(event.target.value);
+ }
- return (
-
-
- Sprache
-
- Deutsch
- English
-
-
-
+ render(){
+ return(
+
+ {Blockly.Msg.settings_language}
+ {Blockly.Msg.settings_language_text}
+
+ {Blockly.Msg.settings_language}
+
+ {Blockly.Msg.settings_language_de}
+ {Blockly.Msg.settings_language_en}
+
+
+
);
+ }
}
+
+LanguageSelector.propTypes = {
+ setLanguage: PropTypes.func.isRequired,
+ language: PropTypes.string.isRequired
+};
+
+const mapStateToProps = state => ({
+ language: state.general.language
+});
+
+export default connect(mapStateToProps, { setLanguage })(LanguageSelector);
diff --git a/src/components/Settings/RenderSelector.js b/src/components/Settings/RenderSelector.js
index 5cf7a9f..7359283 100644
--- a/src/components/Settings/RenderSelector.js
+++ b/src/components/Settings/RenderSelector.js
@@ -1,45 +1,57 @@
-import React from 'react';
-import { makeStyles } from '@material-ui/core/styles';
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import { connect } from 'react-redux';
+import { setRenderer } from '../../actions/generalActions';
+
+import * as Blockly from 'blockly/core'
+
import InputLabel from '@material-ui/core/InputLabel';
import MenuItem from '@material-ui/core/MenuItem';
import FormControl from '@material-ui/core/FormControl';
import Select from '@material-ui/core/Select';
+import Typography from '@material-ui/core/Typography';
+import FormHelperText from '@material-ui/core/FormHelperText';
-const useStyles = makeStyles((theme) => ({
- formControl: {
- margin: theme.spacing(1),
- minWidth: 400,
- },
- selectEmpty: {
- marginTop: theme.spacing(2),
- },
-}));
-export default function RenderSelector() {
- const classes = useStyles();
- const [renderer, setRenderer] = React.useState(window.localStorage.getItem('renderer'));
+class RenderSelector extends Component {
- const handleChange = (event) => {
- setRenderer(event.target.value);
- window.localStorage.setItem('renderer', event.target.value);
- };
+ componentDidMount(){
+ // Ensure that Blockly.setLocale is adopted in the component.
+ // Otherwise, the text will not be displayed until the next update of the component.
+ this.forceUpdate();
+ }
+ render(){
return (
-
-
- Renderer
-
- Geras
- Zelos
-
-
-
Der Renderer bestimmt das aussehen der Blöcke
-
+
+ {Blockly.Msg.settings_renderer}
+ {Blockly.Msg.settings_renderer_text}
+
+ {Blockly.Msg.settings_renderer}
+ this.props.setRenderer(e.target.value)}
+ >
+ Geras
+ Zelos
+
+
+
);
+ }
}
+
+RenderSelector.propTypes = {
+ setRenderer: PropTypes.func.isRequired,
+ language: PropTypes.string.isRequired,
+ renderer: PropTypes.string.isRequired
+};
+
+const mapStateToProps = state => ({
+ renderer: state.general.renderer,
+ language: state.general.language
+});
+
+export default connect(mapStateToProps, { setRenderer })(RenderSelector);
diff --git a/src/components/Settings/Settings.js b/src/components/Settings/Settings.js
index cbbedc9..24b3bfa 100644
--- a/src/components/Settings/Settings.js
+++ b/src/components/Settings/Settings.js
@@ -1,32 +1,65 @@
import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import { connect } from 'react-redux';
+
import { withRouter } from 'react-router-dom';
-import Button from '@material-ui/core/Button';
-import Typography from '@material-ui/core/Typography';
+import * as Blockly from 'blockly/core';
+
+import Breadcrumbs from '../Breadcrumbs';
import LanguageSelector from './LanguageSelector';
import RenderSelector from './RenderSelector';
import StatsSelector from './StatsSelector';
+import Button from '@material-ui/core/Button';
+import Paper from '@material-ui/core/Paper';
class Settings extends Component {
- render() {
- return (
-
- Einstellungen
-
-
-
- { this.props.history.push('/') }}
- >
- Zurück zur Startseite
-
-
- );
- };
+
+ componentDidMount(){
+ // Ensure that Blockly.setLocale is adopted in the component.
+ // Otherwise, the text will not be displayed until the next update of the component.
+ this.forceUpdate();
+ }
+
+ render() {
+ return (
+
+
+
+
{Blockly.Msg.settings_head}
+
+
+
+
+
+
+
+
+
+
+
+
0 ? () => this.props.history.goBack() : () => this.props.history.push('/')}
+ >
+ {Blockly.Msg.button_back}
+
+
+ );
+ };
}
-export default withRouter(Settings);
+Settings.propTypes = {
+ language: PropTypes.string.isRequired,
+ pageVisits: PropTypes.number.isRequired
+};
+
+const mapStateToProps = state => ({
+ language: state.general.language,
+ pageVisits: state.general.pageVisits
+});
+
+export default connect(mapStateToProps, null)(withRouter(Settings));
diff --git a/src/components/Settings/StatsSelector.js b/src/components/Settings/StatsSelector.js
index 8c1322d..b0b3cfe 100644
--- a/src/components/Settings/StatsSelector.js
+++ b/src/components/Settings/StatsSelector.js
@@ -1,44 +1,56 @@
-import React from 'react';
-import { makeStyles } from '@material-ui/core/styles';
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import { connect } from 'react-redux';
+import { setStatistics } from '../../actions/generalActions';
+
+import * as Blockly from 'blockly/core'
+
import InputLabel from '@material-ui/core/InputLabel';
import MenuItem from '@material-ui/core/MenuItem';
import FormControl from '@material-ui/core/FormControl';
import Select from '@material-ui/core/Select';
+import Typography from '@material-ui/core/Typography';
+import FormHelperText from '@material-ui/core/FormHelperText';
-const useStyles = makeStyles((theme) => ({
- formControl: {
- margin: theme.spacing(1),
- minWidth: 400,
- },
- selectEmpty: {
- marginTop: theme.spacing(2),
- },
-}));
+class StatsSelector extends Component {
-export default function StatsSelector() {
- const classes = useStyles();
- const [stats, setStats] = React.useState(window.localStorage.getItem('stats'));
-
- const handleChange = (event) => {
- setStats(event.target.value);
- window.localStorage.setItem('stats', event.target.value);
- };
+ componentDidMount(){
+ // Ensure that Blockly.setLocale is adopted in the component.
+ // Otherwise, the text will not be displayed until the next update of the component.
+ this.forceUpdate();
+ }
+ render(){
return (
-
-
- Statistiken
-
- On
- Off
-
-
-
Schaltet die Statistiken Oberhalb der Arbeitsfläche ein bzw. aus
-
+
+ {Blockly.Msg.settings_statistics}
+ {Blockly.Msg.settings_statistics_text}
+
+ {Blockly.Msg.settings_statistics}
+ this.props.setStatistics(e.target.value)}
+ >
+ {Blockly.Msg.settings_statistics_on}
+ {Blockly.Msg.settings_statistics_off}
+
+
+
);
+ }
}
+
+StatsSelector.propTypes = {
+ setStatistics: PropTypes.func.isRequired,
+ language: PropTypes.string.isRequired,
+ statistics: PropTypes.bool.isRequired
+};
+
+const mapStateToProps = state => ({
+ statistics: state.general.statistics,
+ language: state.general.language
+});
+
+export default connect(mapStateToProps, { setStatistics })(StatsSelector);
diff --git a/src/components/Tutorial/Assessment.js b/src/components/Tutorial/Assessment.js
index 75e180d..c869cc5 100644
--- a/src/components/Tutorial/Assessment.js
+++ b/src/components/Tutorial/Assessment.js
@@ -11,6 +11,7 @@ import withWidth, { isWidthDown } from '@material-ui/core/withWidth';
import Grid from '@material-ui/core/Grid';
import Card from '@material-ui/core/Card';
import Typography from '@material-ui/core/Typography';
+import * as Blockly from 'blockly'
class Assessment extends Component {
@@ -45,7 +46,7 @@ class Assessment extends Component {
- Arbeitsauftrag
+ {Blockly.Msg.tutorials_assessment_task}
{currentTask.text}
diff --git a/src/components/Tutorial/Badge.js b/src/components/Tutorial/Badge.js
index 97103fa..2727fa5 100644
--- a/src/components/Tutorial/Badge.js
+++ b/src/components/Tutorial/Badge.js
@@ -11,6 +11,7 @@ import { withStyles } from '@material-ui/core/styles';
import Paper from '@material-ui/core/Paper';
import Typography from '@material-ui/core/Typography';
import Avatar from '@material-ui/core/Avatar';
+import * as Blockly from 'blockly';
const styles = (theme) => ({
link: {
@@ -32,22 +33,22 @@ class Badge extends Component {
content: ''
};
- componentDidUpdate(props){
- if(this.props.message.id === 'TUTORIAL_CHECK_SUCCESS'){
- if(this.props.tutorial.badge){
+ componentDidUpdate(props) {
+ if (this.props.message.id === 'TUTORIAL_CHECK_SUCCESS') {
+ if (this.props.tutorial.badge) {
// is connected to MyBadges?
- if(this.props.isAuthenticated && this.props.user && this.props.user.badge){
- if(this.props.user.badges && !this.props.user.badges.includes(this.props.tutorial.badge)){
- if(this.isSuccess()){
+ if (this.props.isAuthenticated && this.props.user && this.props.user.badge) {
+ if (this.props.user.badges && !this.props.user.badges.includes(this.props.tutorial.badge)) {
+ if (this.isSuccess()) {
this.props.assigneBadge(this.props.tutorial.badge);
}
}
}
}
}
- if(props.message !== this.props.message){
- if(this.props.message.id === 'ASSIGNE_BADGE_SUCCESS'){
- this.setState({title: `Badge: ${this.props.message.msg.name}`, content: `Herzlichen Glückwunsch! Du hast den Badge ${this.props.message.msg.name} erhalten.`, open: true});
+ if (props.message !== this.props.message) {
+ if (this.props.message.id === 'ASSIGNE_BADGE_SUCCESS') {
+ this.setState({ title: `Badge: ${this.props.message.msg.name}`, content: `${Blockly.Msg.badges_ASSIGNE_BADGE_SUCCESS_01} ${this.props.message.msg.name} ${Blockly.Msg.badges_ASSIGNE_BADGE_SUCCESS_02}`, open: true });
}
}
}
@@ -57,7 +58,7 @@ class Badge extends Component {
var status = this.props.status.filter(status => status._id === tutorialId)[0];
var tasks = status.tasks;
var success = tasks.filter(task => task.type === 'success').length / tasks.length;
- if(success===1){
+ if (success === 1) {
return true;
}
return false;
@@ -74,21 +75,21 @@ class Badge extends Component {
open={this.state.open}
title={this.state.title}
content={this.state.content}
- onClose={() => {this.toggleDialog();}}
- onClick={() => {this.toggleDialog();}}
- button={'Schließen'}
+ onClose={() => { this.toggleDialog(); }}
+ onClick={() => { this.toggleDialog(); }}
+ button={Blockly.Msg.button_close}
>
-
+
{this.props.message.msg.image && this.props.message.msg.image.path ?
-
- : }
-
- {this.props.message.msg.name}
+
+ : }
+
+ {this.props.message.msg.name}
-
- Eine Übersicht über alle erhaltenen Badges im Kontext Blockly for senseBox findest du hier.
+
+ {Blockly.Msg.badges_explaination} {Blockly.Msg.labels_here}.
diff --git a/src/components/Tutorial/Builder/BlocklyExample.js b/src/components/Tutorial/Builder/BlocklyExample.js
index 01f52f4..75dc222 100644
--- a/src/components/Tutorial/Builder/BlocklyExample.js
+++ b/src/components/Tutorial/Builder/BlocklyExample.js
@@ -29,7 +29,7 @@ const styles = (theme) => ({
marginTop: '5px',
height: '40px',
backgroundColor: theme.palette.error.dark,
- '&:hover':{
+ '&:hover': {
backgroundColor: theme.palette.error.dark
}
}
@@ -37,16 +37,16 @@ const styles = (theme) => ({
class BlocklyExample extends Component {
- constructor(props){
+ constructor(props) {
super(props);
- this.state={
+ this.state = {
checked: props.task ? props.task : props.value ? true : false,
input: null,
disabled: false
};
}
- componentDidMount(){
+ componentDidMount() {
moment.updateLocale('de', localization);
this.isError();
// if(this.props.task){
@@ -54,42 +54,42 @@ class BlocklyExample extends Component {
// }
}
- componentDidUpdate(props, state){
- if(props.task !== this.props.task || props.value !== this.props.value){
- this.setState({checked: this.props.task ? this.props.task : this.props.value ? true : false},
+ componentDidUpdate(props, state) {
+ if (props.task !== this.props.task || props.value !== this.props.value) {
+ this.setState({ checked: this.props.task ? this.props.task : this.props.value ? true : false },
() => this.isError()
);
}
- if(state.checked !== this.state.checked && this.state.checked){
+ if (state.checked !== this.state.checked && this.state.checked) {
this.isError();
}
- if(props.xml !== this.props.xml){
+ if (props.xml !== this.props.xml) {
// check if there is at least one block, otherwise the workspace cannot be submitted
var workspace = Blockly.getMainWorkspace();
var areBlocks = workspace.getAllBlocks().length > 0;
- this.setState({disabled: !areBlocks});
+ this.setState({ disabled: !areBlocks });
}
}
isError = () => {
- if(this.state.checked){
+ if (this.state.checked) {
var xml = this.props.value;
// check if value is valid xml;
- try{
+ try {
Blockly.Xml.textToDom(xml);
this.props.deleteError(this.props.index, 'xml');
}
- catch(err){
+ catch (err) {
xml = initialXml;
// not valid xml, throw error in redux store
this.props.setError(this.props.index, 'xml');
}
- if(!this.props.task){
+ if (!this.props.task) {
// instruction can also display only one block, which does not necessarily
// have to be the initial block
xml = xml.replace('deletable="false"', 'deletable="true"');
}
- this.setState({xml: xml});
+ this.setState({ xml: xml });
}
else {
this.props.deleteError(this.props.index, 'xml');
@@ -98,8 +98,8 @@ class BlocklyExample extends Component {
onChange = (value) => {
var oldValue = this.state.checked;
- this.setState({checked: value});
- if(oldValue !== value && !value){
+ this.setState({ checked: value });
+ if (oldValue !== value && !value) {
this.props.deleteError(this.props.index, 'xml');
this.props.deleteProperty(this.props.index, 'xml');
}
@@ -108,12 +108,12 @@ class BlocklyExample extends Component {
setXml = () => {
var xml = this.props.xml;
this.props.changeContent(xml, this.props.index, 'xml');
- this.setState({input: moment(Date.now()).format('LTS')});
+ this.setState({ input: moment(Date.now()).format('LTS') });
}
render() {
return (
-
+
{!this.props.task ?
}
/>
- :
Musterlösung }
+ :
{Blockly.Msg.builder_solution} }
{this.state.checked ? !this.props.value || this.props.error ?
-
{`Reiche deine Blöcke ein, indem du auf den '${this.props.task ? 'Musterlösung einreichen' : 'Beispiel einreichen'}'-Button klickst.`}
- : this.state.input ?
Die letzte Einreichung erfolgte um {this.state.input} Uhr. : null
- : null}
+
{`Reiche deine Blöcke ein, indem du auf den '${this.props.task ? Blockly.Msg.builder_solution_submit : Blockly.Msg.builder_example_submit}'-Button klickst.`}
+ : this.state.input ?
Die letzte Einreichung erfolgte um {this.state.input} Uhr. : null
+ : null}
{this.state.checked && !this.props.task ?
-
Anmerkung: Man kann den initialen Setup()- bzw. Endlosschleifen()-Block löschen. Zusätzlich ist es möglich u.a. nur einen beliebigen Block auszuwählen, ohne dass dieser als deaktiviert dargestellt wird.
- : null}
+
{Blockly.Msg.builder_comment}
+ : null}
{/* ensure that the correct xml-file is displayed in the workspace */}
- {this.state.checked && this.state.xml? (() => {
- return(
-
+ {this.state.checked && this.state.xml ? (() => {
+ return (
+
this.setXml()}
>
- {this.props.task ? 'Musterlösung einreichen' : 'Beispiel einreichen'}
+ {this.props.task ? Blockly.Msg.builder_solution_submit : Blockly.Msg.builder_example_submit}
- )})()
- : null}
+ )
+ })()
+ : null}
);
};
@@ -179,4 +180,4 @@ const mapStateToProps = state => ({
});
-export default connect(mapStateToProps, { changeContent, deleteProperty, setError, deleteError })(withStyles(styles, {withTheme: true})(BlocklyExample));
+export default connect(mapStateToProps, { changeContent, deleteProperty, setError, deleteError })(withStyles(styles, { withTheme: true })(BlocklyExample));
diff --git a/src/components/Tutorial/Builder/Builder.js b/src/components/Tutorial/Builder/Builder.js
index bd4e8a0..40595cc 100644
--- a/src/components/Tutorial/Builder/Builder.js
+++ b/src/components/Tutorial/Builder/Builder.js
@@ -8,8 +8,6 @@ import { clearMessages } from '../../../actions/messageActions';
import axios from 'axios';
import { withRouter } from 'react-router-dom';
-import { saveAs } from 'file-saver';
-import { detectWhitespacesAndReturnReadableResult } from '../../../helpers/whitespace';
import Breadcrumbs from '../../Breadcrumbs';
import Badge from './Badge';
@@ -44,7 +42,7 @@ const styles = (theme) => ({
marginTop: '5px',
height: '40px',
backgroundColor: theme.palette.error.dark,
- '&:hover':{
+ '&:hover': {
backgroundColor: theme.palette.error.dark
}
}
@@ -87,11 +85,11 @@ class Builder extends Component {
// alert(this.props.message.msg);
this.props.clearMessages();
}
- else if(this.props.message.id === 'TUTORIAL_DELETE_SUCCESS'){
+ else if (this.props.message.id === 'TUTORIAL_DELETE_SUCCESS') {
this.onChange('new');
this.setState({ snackbar: true, key: Date.now(), message: `Das Tutorial wurde erfolgreich gelöscht.`, type: 'success' });
}
- else if(this.props.message.id === 'TUTORIAL_DELETE_FAIL'){
+ else if (this.props.message.id === 'TUTORIAL_DELETE_FAIL') {
this.setState({ snackbar: true, key: Date.now(), message: `Fehler beim Löschen des Tutorials. Versuche es noch einmal.`, type: 'error' });
}
}
@@ -100,7 +98,7 @@ class Builder extends Component {
componentWillUnmount() {
this.resetFull();
this.props.resetTutorial();
- if(this.props.message.msg){
+ if (this.props.message.msg) {
this.props.clearMessages();
}
}
@@ -153,12 +151,12 @@ class Builder extends Component {
onChange = (value) => {
this.props.resetTutorialBuilder();
this.props.tutorialId('');
- this.setState({tutorial: value});
+ this.setState({ tutorial: value });
}
onChangeId = (value) => {
this.props.tutorialId(value);
- if(this.state.tutorial === 'change'){
+ if (this.state.tutorial === 'change') {
this.props.progress(true);
var tutorial = this.props.tutorials.filter(tutorial => tutorial._id === value)[0];
this.props.readJSON(tutorial);
@@ -201,8 +199,8 @@ class Builder extends Component {
newTutorial.append(`steps[${i}][type]`, step.type);
newTutorial.append(`steps[${i}][headline]`, step.headline);
newTutorial.append(`steps[${i}][text]`, step.text);
- if(i === 0 && step.type === 'instruction'){
- if(step.requirements){ // optional
+ if (i === 0 && step.type === 'instruction') {
+ if (step.requirements) { // optional
step.requirements.forEach((requirement, j) => {
newTutorial.append(`steps[${i}][requirements][${j}]`, requirement);
});
@@ -211,14 +209,14 @@ class Builder extends Component {
newTutorial.append(`steps[${i}][hardware][${j}]`, hardware);
});
}
- if(step.xml){ // optional
+ if (step.xml) { // optional
newTutorial.append(`steps[${i}][xml]`, step.xml);
}
- if(step.media){ // optional
- if(step.media.youtube){
+ if (step.media) { // optional
+ if (step.media.youtube) {
newTutorial.append(`steps[${i}][media][youtube]`, step.media.youtube);
}
- if(step.media.picture){
+ if (step.media.picture) {
newTutorial.append(`steps[${i}][media][picture]`, step.media.picture);
}
}
@@ -282,30 +280,30 @@ class Builder extends Component {
Tutorial-Builder
this.onChange(e.target.value)}>
- }
label="neues Tutorial erstellen"
labelPlacement="end"
/>
{filteredTutorials.length > 0 ?
-
- }
- label="bestehendes Tutorial ändern"
- labelPlacement="end"
- />
- }
- label="bestehendes Tutorial löschen"
- labelPlacement="end"
- />
-
- : null}
+
+ }
+ label="bestehendes Tutorial ändern"
+ labelPlacement="end"
+ />
+ }
+ label="bestehendes Tutorial löschen"
+ labelPlacement="end"
+ />
+
+ : null}
@@ -325,7 +323,7 @@ class Builder extends Component {
this.uploadJsonString()}>String laden
- :
+ :
Tutorial
)}
- {/*submit or reset*/}
-
- {this.state.tutorial === 'new' ?
-
- this.submitNew()}>Tutorial erstellen
- this.resetFull()}>Zurücksetzen
-
- :
- this.submitUpdate()}>Tutorial ändern
- this.resetTutorial()}>Zurücksetzen
+
+
+
- }
-
-
-
-
-
- : null}
+ : null}
{this.state.tutorial === 'delete' && this.props.id !== '' ?
this.props.deleteTutorial()}>Tutorial löschen
- : null}
+ : null}
({
multiGridListTile: {
@@ -67,8 +69,8 @@ class Requirements extends Component {
return (
Hardware
-
Beachte, dass die Reihenfolge des Auswählens maßgebend ist.
- {this.props.error ?
Wähle mindestens eine Hardware-Komponente aus. : null}
+
{Blockly.Msg.builder_hardware_order}
+ {this.props.error ?
{Blockly.Msg.builder_hardware_helper} : null}
{hardware.map((picture, i) => (
this.onChange(picture.id)} classes={{ tile: this.props.value.filter(value => value === picture.id).length > 0 ? this.props.classes.active : this.props.classes.border }}>
diff --git a/src/components/Tutorial/Builder/Requirements.js b/src/components/Tutorial/Builder/Requirements.js
index d5bd2ca..dfb542b 100644
--- a/src/components/Tutorial/Builder/Requirements.js
+++ b/src/components/Tutorial/Builder/Requirements.js
@@ -2,8 +2,6 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { changeContent } from '../../../actions/tutorialBuilderActions';
-import { getTutorials, resetTutorial } from '../../../actions/tutorialActions';
-import { clearMessages } from '../../../actions/messageActions';
import FormGroup from '@material-ui/core/FormGroup';
import Checkbox from '@material-ui/core/Checkbox';
@@ -11,7 +9,7 @@ import FormControlLabel from '@material-ui/core/FormControlLabel';
import FormLabel from '@material-ui/core/FormLabel';
import FormHelperText from '@material-ui/core/FormHelperText';
import FormControl from '@material-ui/core/FormControl';
-
+import * as Blockly from 'blockly'
class Requirements extends Component {
onChange = (e) => {
@@ -29,8 +27,8 @@ class Requirements extends Component {
render() {
return (
- Voraussetzungen
- Beachte, dass die Reihenfolge des Anhakens maßgebend ist.
+ {Blockly.Msg.builder_requirements_head}
+ {Blockly.Msg.builder_requirements_order}
{this.props.tutorials.filter(tutorial => tutorial._id !== this.props.id).map((tutorial, i) =>
({
expand: {
'&:hover': {
@@ -56,7 +56,7 @@ class Hardware extends Component {
var cols = isWidthDown('md', this.props.width) ? isWidthDown('sm', this.props.width) ? isWidthDown('xs', this.props.width) ? 2 : 3 : 4 : 6;
return (
-
Für die Umsetzung benötigst du folgende Hardware:
+
{Blockly.Msg.tutorials_hardware_head}
{this.props.picture.map((picture, i) => {
@@ -91,11 +91,11 @@ class Hardware extends Component {
content={this.state.content}
onClose={this.handleClose}
onClick={this.handleClose}
- button={'Schließen'}
+ button={Blockly.Msg.button_close}
>
- Weitere Informationen zur Hardware-Komponente findest du
hier.
+ {Blockly.Msg.tutorials_hardware_moreInformation}
{Blockly.Msg.tutorials_hardware_here}.
diff --git a/src/components/Tutorial/HintTutorialExists.js b/src/components/Tutorial/HintTutorialExists.js
index 4b1fa2d..0c86c53 100644
--- a/src/components/Tutorial/HintTutorialExists.js
+++ b/src/components/Tutorial/HintTutorialExists.js
@@ -9,6 +9,7 @@ import Dialog from '../Dialog';
import { withStyles } from '@material-ui/core/styles';
import Checkbox from '@material-ui/core/Checkbox';
import FormControlLabel from '@material-ui/core/FormControlLabel';
+import * as Blockly from 'blockly'
const styles = (theme) => ({
link: {
@@ -45,7 +46,7 @@ class HintTutorialExists extends Component {
window.localStorage.setItem('news', e.target.checked);
}
else {
- window.localStorage.deleteItem('news');
+ window.localStorage.removeItem('news');
}
}
@@ -56,30 +57,30 @@ class HintTutorialExists extends Component {
fullWidth
maxWidth={'sm'}
open={this.state.open}
- title={'Neuigkeiten'}
+ title={Blockly.Msg.messages_newblockly_head}
content={''}
onClose={this.toggleDialog}
onClick={this.toggleDialog}
- button={'Schließen'}
+ button={Blockly.Msg.button_close}
>
- Es gibt ab jetzt Tutorials zu verschiedenen Themen. Schau mal hier vorbei.
- this.onChange(e)}
- name="dialog"
- color="primary"
- />
- }
- label={'Dialog nicht mehr anzeigen'}
- />
+ {Blockly.Msg.messages_newblockly_text} test
+ this.onChange(e)}
+ name="dialog"
+ color="primary"
+ />
+ }
+ label={Blockly.Msg.labels_donotshowagain}
+ />
);
};
diff --git a/src/components/Tutorial/Requirement.js b/src/components/Tutorial/Requirement.js
index a3c0c86..87784cc 100644
--- a/src/components/Tutorial/Requirement.js
+++ b/src/components/Tutorial/Requirement.js
@@ -13,6 +13,7 @@ import Tooltip from '@material-ui/core/Tooltip';
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCheck, faTimes } from "@fortawesome/free-solid-svg-icons";
+import * as Blockly from 'blockly'
const styles = theme => ({
outerDiv: {
@@ -63,7 +64,7 @@ class Requirement extends Component {
var tutorialIds = requirements.map(requirement => requirement._id);
return (
-
Bevor du mit diesem Tutorial fortfährst solltest du folgende Tutorials erfolgreich abgeschlossen haben:
+
{Blockly.Msg.tutorials_requirements}
{tutorialIds.map((tutorialId, i) => {
var title = requirements[i].title
diff --git a/src/components/Tutorial/SolutionCheck.js b/src/components/Tutorial/SolutionCheck.js
index f8c1383..ba8c434 100644
--- a/src/components/Tutorial/SolutionCheck.js
+++ b/src/components/Tutorial/SolutionCheck.js
@@ -18,6 +18,8 @@ import Button from '@material-ui/core/Button';
import { faClipboardCheck } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import * as Blockly from 'blockly'
+
const styles = (theme) => ({
compile: {
backgroundColor: theme.palette.button.compile,
@@ -57,7 +59,7 @@ class SolutionCheck extends Component {
const steps = this.props.tutorial.steps;
return (
-
+
{this.state.msg.type === 'success' ?
@@ -88,7 +90,7 @@ class SolutionCheck extends Component {
color="primary"
onClick={() => { this.toggleDialog(); this.props.history.push(`/tutorial/`) }}
>
- Tutorials-Übersicht
+ {Blockly.Msg.button_tutorial_overview}
:
{ this.toggleDialog(); this.props.tutorialStep(this.props.activeStep + 1) }}
>
- nächster Schritt
+ {Blockly.Msg.button_next}
}
diff --git a/src/components/Tutorial/StepperHorizontal.js b/src/components/Tutorial/StepperHorizontal.js
index 9886336..f045621 100644
--- a/src/components/Tutorial/StepperHorizontal.js
+++ b/src/components/Tutorial/StepperHorizontal.js
@@ -51,7 +51,6 @@ class StepperHorizontal extends Component {
render() {
var tutorialId = this.props.tutorial._id;
- var tutorialIndex = this.props.currentTutorialIndex;
var status = this.props.status.filter(status => status._id === tutorialId)[0];
var tasks = status.tasks;
var error = tasks.filter(task => task.type === 'error').length > 0;
@@ -71,7 +70,7 @@ class StepperHorizontal extends Component {
{ this.props.history.push(`/tutorial/${tutorials[tutorialIndex - 1].id}`) }}
+ //onClick={() => { this.props.history.push(`/tutorial/${tutorials[tutorialIndex - 1].id}`) }}
>
{'<'}
@@ -83,7 +82,7 @@ class StepperHorizontal extends Component {
{ this.props.history.push(`/tutorial/${tutorials[tutorialIndex + 1].id}`) }}
+ //onClick={() => { this.props.history.push(`/tutorial/${tutorials[tutorialIndex + 1].id}`) }}
>
{'>'}
diff --git a/src/components/Tutorial/Tutorial.js b/src/components/Tutorial/Tutorial.js
index edec484..b6fd1f7 100644
--- a/src/components/Tutorial/Tutorial.js
+++ b/src/components/Tutorial/Tutorial.js
@@ -12,7 +12,7 @@ import Instruction from './Instruction';
import Assessment from './Assessment';
import Badge from './Badge';
import NotFound from '../NotFound';
-
+import * as Blockly from 'blockly'
import { detectWhitespacesAndReturnReadableResult } from '../../helpers/whitespace';
@@ -38,7 +38,7 @@ class Tutorial extends Component {
else if(this.props.tutorial && !this.props.isLoading && this.props.tutorial._id != this.props.match.params.tutorialId) {
this.props.getTutorial(this.props.match.params.tutorialId);
}
- if(this.props.message.id === 'GET_TUTORIAL_FAIL'){
+ if (this.props.message.id === 'GET_TUTORIAL_FAIL') {
alert(this.props.message.msg);
}
}
@@ -46,7 +46,7 @@ class Tutorial extends Component {
componentWillUnmount() {
this.props.resetTutorial();
this.props.workspaceName(null);
- if(this.props.message.msg){
+ if (this.props.message.msg) {
this.props.clearMessages();
}
}
@@ -56,37 +56,38 @@ class Tutorial extends Component {
{this.props.isLoading ? null :
!this.props.tutorial ?
- this.props.message.id === 'GET_TUTORIAL_FAIL' ?
: null
+ this.props.message.id === 'GET_TUTORIAL_FAIL' ?
: null
: (() => {
- var tutorial = this.props.tutorial;
- var steps = this.props.tutorial.steps;
- var step = steps[this.props.activeStep];
- var name = `${detectWhitespacesAndReturnReadableResult(tutorial.title)}_${detectWhitespacesAndReturnReadableResult(step.headline)}`;
- return(
-
-
+ var tutorial = this.props.tutorial;
+ var steps = this.props.tutorial.steps;
+ var step = steps[this.props.activeStep];
+ var name = `${detectWhitespacesAndReturnReadableResult(tutorial.title)}_${detectWhitespacesAndReturnReadableResult(step.headline)}`;
+ return (
+
+
-
-
+
+
-
-
- {/* calc(Card-padding: 10px + Button-height: 35px + Button-marginTop: 15px)*/}
-
- {step ?
- step.type === 'instruction' ?
-
- : // if step.type === 'assessment'
- : null}
+
+
+ {/* calc(Card-padding: 10px + Button-height: 35px + Button-marginTop: 15px)*/}
+
+ {step ?
+ step.type === 'instruction' ?
+
+ : // if step.type === 'assessment'
+ : null}
-
- this.props.tutorialStep(this.props.activeStep - 1)}>Zurück
- this.props.tutorialStep(this.props.activeStep + 1)}>Weiter
-
-
-
+
+ this.props.tutorialStep(this.props.activeStep - 1)}>Zurück
+ this.props.tutorialStep(this.props.activeStep + 1)}>Weiter
+
+
- )})()
+
+ )
+ })()
}
);
diff --git a/src/components/User/Login.js b/src/components/User/Login.js
index 13d4497..75a4948 100644
--- a/src/components/User/Login.js
+++ b/src/components/User/Login.js
@@ -19,7 +19,7 @@ import Divider from '@material-ui/core/Divider';
import InputAdornment from '@material-ui/core/InputAdornment';
import CircularProgress from '@material-ui/core/CircularProgress';
import Link from '@material-ui/core/Link';
-
+import * as Blockly from 'blockly'
export class Login extends Component {
@@ -37,21 +37,21 @@ export class Login extends Component {
};
}
- componentDidUpdate(props){
+ componentDidUpdate(props) {
console.log(this.state.redirect);
const { message } = this.props;
if (message !== props.message) {
- if(message.id === 'LOGIN_SUCCESS'){
- if(this.state.redirect){
+ if (message.id === 'LOGIN_SUCCESS') {
+ if (this.state.redirect) {
this.props.history.push(this.state.redirect);
}
- else{
+ else {
this.props.history.goBack();
}
}
// Check for login error
- else if(message.id === 'LOGIN_FAIL'){
- this.setState({ email: '', password: '', snackbar: true, key: Date.now(), message: 'Der Benutzername oder das Passwort ist nicht korrekt.', type: 'error' });
+ else if (message.id === 'LOGIN_FAIL') {
+ this.setState({ email: '', password: '', snackbar: true, key: Date.now(), message: Blockly.Msg.messages_LOGIN_FAIL, type: 'error' });
}
}
}
@@ -62,8 +62,8 @@ export class Login extends Component {
onSubmit = e => {
e.preventDefault();
- const {email, password} = this.state;
- if(email !== '' && password !== ''){
+ const { email, password } = this.state;
+ if (email !== '' && password !== '') {
// create user object
const user = {
email,
@@ -83,13 +83,13 @@ export class Login extends Component {
e.preventDefault();
};
- render(){
- return(
+ render() {
+ return (
-
-
Anmelden
+
+
{Blockly.Msg.login_head}
Zur Anmeldung ist ein Konto auf openSenseMap Voraussetzung.
@@ -100,10 +100,10 @@ export class Login extends Component {
key={this.state.key}
/>
-
+
{this.props.progress ?
-
- : 'Anmelden'}
+
+ : 'Anmelden'}
-
+
Passwort vergessen?
-
-
+
+
Du hast noch kein Konto? Registriere dich auf openSenseMap.
@@ -156,7 +156,6 @@ Login.propTypes = {
message: PropTypes.object.isRequired,
login: PropTypes.func.isRequired,
clearMessages: PropTypes.func.isRequired,
- message: PropTypes.object.isRequired,
progress: PropTypes.bool.isRequired
};
diff --git a/src/components/Workspace/Compile.js b/src/components/Workspace/Compile.js
index f8a204a..648931f 100644
--- a/src/components/Workspace/Compile.js
+++ b/src/components/Workspace/Compile.js
@@ -17,6 +17,7 @@ import TextField from '@material-ui/core/TextField';
import { faClipboardCheck } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import * as Blockly from 'blockly/core';
const styles = (theme) => ({
backdrop: {
@@ -85,7 +86,7 @@ class Compile extends Component {
})
.catch(err => {
console.log(err);
- this.setState({ progress: false, file: false, open: true, title: 'Fehler', content: 'Etwas ist beim Kompilieren schief gelaufen. Versuche es nochmal.' });
+ this.setState({ progress: false, file: false, open: true, title: Blockly.Msg.compiledialog_headline, content: Blockly.Msg.compiledialog_text });
});
}
@@ -119,7 +120,7 @@ class Compile extends Component {
return (
{this.props.iconButton ?
-
+
this.compile()}
@@ -141,7 +142,7 @@ class Compile extends Component {
content={this.state.content}
onClose={this.toggleDialog}
onClick={this.state.file ? () => { this.toggleDialog(); this.setState({ name: this.props.name }) } : this.toggleDialog}
- button={this.state.file ? 'Abbrechen' : 'Schließen'}
+ button={this.state.file ? Blockly.Msg.button_cancel : Blockly.Msg.button_close}
>
{this.state.file ?
diff --git a/src/components/Workspace/DeleteProject.js b/src/components/Workspace/DeleteProject.js
index 3df813d..4566916 100644
--- a/src/components/Workspace/DeleteProject.js
+++ b/src/components/Workspace/DeleteProject.js
@@ -13,6 +13,7 @@ import Tooltip from '@material-ui/core/Tooltip';
import { faTrashAlt } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import * as Blockly from 'blockly/core';
const styles = (theme) => ({
buttonTrash: {
@@ -43,12 +44,12 @@ class DeleteProject extends Component {
}
componentDidUpdate(props) {
- if(this.props.message !== props.message){
- if(this.props.message.id === 'PROJECT_DELETE_SUCCESS'){
+ if (this.props.message !== props.message) {
+ if (this.props.message.id === 'PROJECT_DELETE_SUCCESS') {
this.props.history.push(`/${this.props.projectType}`);
}
- else if(this.props.message.id === 'PROJECT_DELETE_FAIL'){
- this.setState({ snackbar: true, key: Date.now(), message: `Fehler beim Löschen des Projektes. Versuche es noch einmal.`, type: 'error' });
+ else if (this.props.message.id === 'PROJECT_DELETE_FAIL') {
+ this.setState({ snackbar: true, key: Date.now(), message: Blockly.Msg.messages_delete_project_failed, type: 'error' });
}
}
}
@@ -56,7 +57,7 @@ class DeleteProject extends Component {
render() {
return (
-
+
this.props.deleteProject(this.props.projectType, this.props.project._id)}
diff --git a/src/components/Workspace/DownloadProject.js b/src/components/Workspace/DownloadProject.js
index 9b30273..1315625 100644
--- a/src/components/Workspace/DownloadProject.js
+++ b/src/components/Workspace/DownloadProject.js
@@ -12,6 +12,8 @@ import Tooltip from '@material-ui/core/Tooltip';
import { faFileDownload } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import * as Blockly from 'blockly/core';
+
const styles = (theme) => ({
button: {
@@ -40,7 +42,7 @@ class DownloadProject extends Component {
render() {
return (
-
+
this.downloadXmlFile()}
diff --git a/src/components/Workspace/OpenProject.js b/src/components/Workspace/OpenProject.js
index 6038a49..5387e89 100644
--- a/src/components/Workspace/OpenProject.js
+++ b/src/components/Workspace/OpenProject.js
@@ -9,10 +9,7 @@ import Snackbar from '../Snackbar';
import Dialog from '../Dialog';
import { withStyles } from '@material-ui/core/styles';
-import Button from '@material-ui/core/Button';
-import IconButton from '@material-ui/core/IconButton';
import Tooltip from '@material-ui/core/Tooltip';
-import Typography from '@material-ui/core/Typography';
import { faUpload } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
@@ -97,7 +94,7 @@ class OpenProject extends Component {
type="file"
/>
-
+
-
+
this.resetWorkspace()}
diff --git a/src/components/Workspace/SaveProject.js b/src/components/Workspace/SaveProject.js
index 1a9ff3d..a71e968 100644
--- a/src/components/Workspace/SaveProject.js
+++ b/src/components/Workspace/SaveProject.js
@@ -14,13 +14,14 @@ import Button from '@material-ui/core/Button';
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 Menu from '@material-ui/core/Menu';
import MenuItem from '@material-ui/core/MenuItem';
import { faSave } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import * as Blockly from 'blockly/core'
+
const styles = (theme) => ({
button: {
backgroundColor: theme.palette.primary.main,
@@ -63,18 +64,18 @@ class SaveProject extends Component {
if (props.description !== this.props.description) {
this.setState({ description: this.props.description });
}
- if(this.props.message !== props.message){
- if(this.props.message.id === 'PROJECT_UPDATE_SUCCESS'){
- this.setState({ snackbar: true, key: Date.now(), message: `Das Projekt wurde erfolgreich aktualisiert.`, type: 'success' });
+ if (this.props.message !== props.message) {
+ if (this.props.message.id === 'PROJECT_UPDATE_SUCCESS') {
+ this.setState({ snackbar: true, key: Date.now(), message: Blockly.Msg.messages_PROJECT_UPDATE_SUCCESS, type: 'success' });
}
- else if(this.props.message.id === 'GALLERY_UPDATE_SUCCESS'){
- this.setState({ snackbar: true, key: Date.now(), message: `Das Galerie-Projekt wurde erfolgreich aktualisiert.`, type: 'success' });
+ else if (this.props.message.id === 'GALLERY_UPDATE_SUCCESS') {
+ this.setState({ snackbar: true, key: Date.now(), message: Blockly.Msg.messages_GALLERY_UPDATE_SUCCESS, type: 'success' });
}
- else if(this.props.message.id === 'PROJECT_UPDATE_FAIL'){
- this.setState({ snackbar: true, key: Date.now(), message: `Fehler beim Aktualisieren des Projektes. Versuche es noch einmal.`, type: 'error' });
+ else if (this.props.message.id === 'PROJECT_UPDATE_FAIL') {
+ this.setState({ snackbar: true, key: Date.now(), message: Blockly.Msg.messages_PROJECT_UPDATE_FAIL, type: 'error' });
}
- else if(this.props.message.id === 'GALLERY_UPDATE_FAIL'){
- this.setState({ snackbar: true, key: Date.now(), message: `Fehler beim Aktualisieren des Galerie-Projektes. Versuche es noch einmal.`, type: 'error' });
+ else if (this.props.message.id === 'GALLERY_UPDATE_FAIL') {
+ this.setState({ snackbar: true, key: Date.now(), message: Blockly.Msg.messages_GALLERY_UPDATE_FAIL, type: 'error' });
}
}
}
@@ -92,16 +93,16 @@ class SaveProject extends Component {
xml: this.props.xml,
title: this.props.name
};
- if(this.state.projectType === 'gallery'){
+ if (this.state.projectType === 'gallery') {
body.description = this.state.description;
}
const config = {
success: res => {
var project = res.data[this.state.projectType];
this.props.history.push(`/${this.state.projectType}/${project._id}`);
- },
- error: err => {
- this.setState({ snackbar: true, key: Date.now(), message: `Fehler beim Speichern des ${this.state.projectType === 'gallery' ? 'Galerie-':''}Projektes. Versuche es noch einmal.`, type: 'error' });
+ })
+ .catch(err => {
+ this.setState({ snackbar: true, key: Date.now(), message: `${Blockly.Msg.messages_gallery_save_fail_1} ${this.state.projectType === 'gallery' ? 'Galerie-' : ''} ${Blockly.Msg.messages_gallery_save_fail_2}`, type: 'error' });
window.scrollTo(0, 0);
}
};
@@ -120,7 +121,7 @@ class SaveProject extends Component {
workspaceDescription = () => {
this.props.setDescription(this.state.description);
- this.setState({projectType: 'gallery'},
+ this.setState({ projectType: 'gallery' },
() => this.saveProject()
);
}
@@ -129,10 +130,10 @@ class SaveProject extends Component {
console.log(1, this.props);
return (
-
+
this.toggleMenu(e) : this.state.projectType === 'project' ? () => this.props.updateProject(this.state.projectType, this.props.project._id) : () => {this.setState({projectType: 'project'}, () => this.saveProject())}}
+ onClick={this.props.user.blocklyRole !== 'user' && (!this.props.project || this.props.user.email === this.props.project.creator) ? (e) => this.toggleMenu(e) : this.state.projectType === 'project' ? () => this.props.updateProject(this.state.projectType, this.props.project._id) : () => { this.setState({ projectType: 'project' }, () => this.saveProject()) }}
>
@@ -152,12 +153,12 @@ class SaveProject extends Component {
onClose={this.toggleMenu}
>
{this.toggleMenu(e); this.props.updateProject(this.state.projectType, this.props.project._id)} : (e) => {this.toggleMenu(e); this.setState({projectType: 'project'}, () => this.saveProject())}}
+ onClick={this.state.projectType === 'project' ? (e) => { this.toggleMenu(e); this.props.updateProject(this.state.projectType, this.props.project._id) } : (e) => { this.toggleMenu(e); this.setState({ projectType: 'project' }, () => this.saveProject()) }}
>
- {this.state.projectType === 'project' ? 'Projekt aktualisieren' : 'Projekt erstellen'}
+ {this.state.projectType === 'project' ? Blockly.Msg.tooltip_update_project : Blockly.Msg.tooltip_create_project}
{this.toggleMenu(e); this.props.updateProject(this.state.projectType, this.props.project._id)} : (e) => {this.toggleMenu(e); this.setState({ open: true, title: 'Projekbeschreibung ergänzen', content: 'Bitte gib eine Beschreibung für das Galerie-Projekt ein und bestätige deine Angabe mit einem Klick auf \'Eingabe\'.'});}}
+ onClick={this.state.projectType === 'gallery' ? (e) => { this.toggleMenu(e); this.props.updateProject(this.state.projectType, this.props.project._id) } : (e) => { this.toggleMenu(e); this.setState({ open: true, title: 'Projekbeschreibung ergänzen', content: 'Bitte gib eine Beschreibung für das Galerie-Projekt ein und bestätige deine Angabe mit einem Klick auf \'Eingabe\'.' }); }}
>
{this.state.projectType === 'gallery' ? 'Galerie-Projekt aktualisieren' : 'Galerie-Projekt erstellen'}
@@ -173,13 +174,13 @@ class SaveProject extends Component {
open={this.state.open}
title={this.state.title}
content={this.state.content}
- onClose={() => {this.toggleDialog(); this.setState({ description: this.props.description });}}
- onClick={() => {this.toggleDialog(); this.setState({ description: this.props.description });}}
+ onClose={() => { this.toggleDialog(); this.setState({ description: this.props.description }); }}
+ onClick={() => { this.toggleDialog(); this.setState({ description: this.props.description }); }}
button={'Abbrechen'}
>
- {this.workspaceDescription(); this.toggleDialog();}}>Eingabe
+ { this.workspaceDescription(); this.toggleDialog(); }}>Eingabe
diff --git a/src/components/Workspace/Screenshot.js b/src/components/Workspace/Screenshot.js
index c150db2..3dfc29b 100644
--- a/src/components/Workspace/Screenshot.js
+++ b/src/components/Workspace/Screenshot.js
@@ -73,7 +73,7 @@ class Screenshot extends Component {
render() {
return (
-
+
this.getSvg()}
diff --git a/src/components/Workspace/ShareProject.js b/src/components/Workspace/ShareProject.js
index 060e0e9..4eb487b 100644
--- a/src/components/Workspace/ShareProject.js
+++ b/src/components/Workspace/ShareProject.js
@@ -19,6 +19,8 @@ import Typography from '@material-ui/core/Typography';
import { faShareAlt, faCopy } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import * as Blockly from 'blockly/core';
+
const styles = (theme) => ({
button: {
backgroundColor: theme.palette.primary.main,
@@ -59,18 +61,18 @@ class WorkspaceFunc extends Component {
}
componentDidUpdate(props) {
- if(this.props.message !== props.message){
- if(this.props.message.id === 'SHARE_SUCCESS' && (!this.props.multiple || this.props.message.status === this.props.project._id)){
- this.setState({ share: true, open: true, title: 'Programm teilen', id: this.props.message.status });
+ if (this.props.message !== props.message) {
+ if (this.props.message.id === 'SHARE_SUCCESS' && (!this.props.multiple || this.props.message.status === this.props.project._id)) {
+ this.setState({ share: true, open: true, title: Blockly.Msg.messages_SHARE_SUCCESS, id: this.props.message.status });
}
- else if(this.props.message.id === 'SHARE_FAIL' && (!this.props.multiple || this.props.message.status === this.props.project._id)){
- this.setState({ snackbar: true, key: Date.now(), message: `Fehler beim Erstellen eines Links zum Teilen deines Programmes. Versuche es noch einmal.`, type: 'error' });
+ else if (this.props.message.id === 'SHARE_FAIL' && (!this.props.multiple || this.props.message.status === this.props.project._id)) {
+ this.setState({ snackbar: true, key: Date.now(), message: Blockly.Msg.messages_SHARE_FAIL, type: 'error' });
window.scrollTo(0, 0);
}
}
}
- componentWillUnmount(){
+ componentWillUnmount() {
this.props.clearMessages();
}
@@ -79,9 +81,9 @@ class WorkspaceFunc extends Component {
}
shareBlocks = () => {
- if(this.props.projectType === 'project' && this.props.project.shared){
+ if (this.props.projectType === 'project' && this.props.project.shared) {
// project is already shared
- this.setState({ open: true, title: 'Programm teilen', id: this.props.project._id });
+ this.setState({ open: true, title: Blockly.Msg.messages_SHARE_SUCCESS, id: this.props.project._id });
}
else {
this.props.shareProject(this.props.name || this.props.project.title, this.props.projectType, this.props.project ? this.props.project._id : undefined);
@@ -91,7 +93,7 @@ class WorkspaceFunc extends Component {
render() {
return (
-
+
this.shareBlocks()}
@@ -112,29 +114,28 @@ class WorkspaceFunc extends Component {
content={this.state.content}
onClose={this.toggleDialog}
onClick={this.toggleDialog}
- button={'Schließen'}
+ button={Blockly.Msg.button_close}
>
Über den folgenden Link kannst du dein Programm teilen:
this.toggleDialog()} className={this.props.classes.link}>{`${window.location.origin}/share/${this.state.id}`}
-
+
{
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' });
+ this.setState({ snackbar: true, key: Date.now(), message: Blockly.Msg.messages_copylink_success, type: 'success' });
}}
>
{this.props.project && this.props.project.shared && this.props.message.id !== 'SHARE_SUCCESS' ?
- {`Das Projekt wurde bereits geteilt. Der Link ist noch mindestens ${
- moment(this.props.project.shared).diff(moment().utc(), 'days') === 0 ?
- moment(this.props.project.shared).diff(moment().utc(), 'hours') === 0 ?
- `${moment(this.props.project.shared).diff(moment().utc(), 'minutes')} Minuten`
+ {`Das Projekt wurde bereits geteilt. Der Link ist noch mindestens ${moment(this.props.project.shared).diff(moment().utc(), 'days') === 0 ?
+ moment(this.props.project.shared).diff(moment().utc(), 'hours') === 0 ?
+ `${moment(this.props.project.shared).diff(moment().utc(), 'minutes')} Minuten`
: `${moment(this.props.project.shared).diff(moment().utc(), 'hours')} Stunden`
: `${moment(this.props.project.shared).diff(moment().utc(), 'days')} Tage`} gültig.`}
- : {`Der Link ist nun ${process.env.REACT_APP_SHARE_LINK_EXPIRES} Tage gültig.`} }
+ : {`Der Link ist nun ${process.env.REACT_APP_SHARE_LINK_EXPIRES} Tage gültig.`} }
diff --git a/src/components/Workspace/TrashcanButtons.js b/src/components/Workspace/TrashcanButtons.js
index 2545d59..de23cb9 100644
--- a/src/components/Workspace/TrashcanButtons.js
+++ b/src/components/Workspace/TrashcanButtons.js
@@ -36,8 +36,8 @@ class TrashcanButtons extends Component {
componentDidUpdate(previousProps, previousState) {
const workspace = Blockly.getMainWorkspace();
const contentsIsOpen = workspace.trashcan.contentsIsOpen();
- if(previousState.closeTrashFlyout !== contentsIsOpen){
- this.setState({ closeTrashFlyout: contentsIsOpen });
+ if (previousState.closeTrashFlyout !== contentsIsOpen) {
+ this.setState({ closeTrashFlyout: contentsIsOpen });
}
}
@@ -59,26 +59,26 @@ class TrashcanButtons extends Component {
return (
this.state.closeTrashFlyout ?
-
+
this.closeTrashcan()}
>
-
+
-
+
this.clearTrashcan()}
>
-
+
- : null
+ : null
);
};
}
diff --git a/src/components/Workspace/WorkspaceName.js b/src/components/Workspace/WorkspaceName.js
index 9efe915..0437f9a 100644
--- a/src/components/Workspace/WorkspaceName.js
+++ b/src/components/Workspace/WorkspaceName.js
@@ -16,6 +16,7 @@ import Typography from '@material-ui/core/Typography';
import { faPen } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import * as Blockly from 'blockly/core'
const styles = (theme) => ({
workspaceName: {
@@ -72,31 +73,31 @@ class WorkspaceName extends Component {
renameWorkspace = () => {
this.props.workspaceName(this.state.name);
this.toggleDialog();
- if(this.props.projectType === 'project' || this.props.projectType === 'gallery' || this.state.projectType === 'gallery'){
- if(this.props.projectType === 'gallery' || this.state.projectType === 'gallery'){
+ if (this.props.projectType === 'project' || this.props.projectType === 'gallery' || this.state.projectType === 'gallery') {
+ if (this.props.projectType === 'gallery' || this.state.projectType === 'gallery') {
this.props.setDescription(this.state.description);
}
- if(this.state.projectType === 'gallery'){
+ if (this.state.projectType === 'gallery') {
this.saveGallery();
} else {
this.props.updateProject(this.props.projectType, this.props.project._id);
}
} else {
- this.setState({ snackbar: true, type: 'success', key: Date.now(), message: `Das Projekt wurde erfolgreich in '${this.state.name}' umbenannt.` });
+ this.setState({ snackbar: true, type: 'success', key: Date.now(), message: `${Blockly.Msg.messages_rename_success_01} ${this.state.name} ${Blockly.Msg.messages_rename_success_02}` });
}
}
render() {
return (
-
+
{if(this.props.multiple){this.props.workspaceName(this.props.project.title);if(this.props.projectType === 'gallery'){this.props.setDescription(this.props.project.description);}} this.setState({ open: true, title: this.props.projectType === 'gallery' ? 'Projektdaten ändern': this.props.projectType === 'project' ? 'Projekt umbenennen' : 'Projekt benennen', content: this.props.projectType === 'gallery' ? 'Bitte gib einen Titel und eine Beschreibung für das Galerie-Projekt ein und bestätige die Angaben mit einem Klick auf \'Eingabe\'.':'Bitte gib einen Namen für das Projekt ein und bestätige diesen mit einem Klick auf \'Eingabe\'.' }) }}
+ onClick={() => { if (this.props.multiple) { this.props.workspaceName(this.props.project.title); if (this.props.projectType === 'gallery') { this.props.setDescription(this.props.project.description); } } this.setState({ open: true, title: this.props.projectType === 'gallery' ? 'Projektdaten ändern' : this.props.projectType === 'project' ? 'Projekt umbenennen' : 'Projekt benennen', content: this.props.projectType === 'gallery' ? 'Bitte gib einen Titel und eine Beschreibung für das Galerie-Projekt ein und bestätige die Angaben mit einem Klick auf \'Eingabe\'.' : 'Bitte gib einen Namen für das Projekt ein und bestätige diesen mit einem Klick auf \'Eingabe\'.' }) }}
>
- {this.props.name && !isWidthDown(this.props.projectType === 'project' || this.props.projectType === 'gallery' ? 'xl':'xs', this.props.width) ?
+ {this.props.name && !isWidthDown(this.props.projectType === 'project' || this.props.projectType === 'gallery' ? 'xl' : 'xs', this.props.width) ?
{this.props.name}
- : null}
+ : null}
@@ -113,17 +114,17 @@ class WorkspaceName extends Component {
open={this.state.open}
title={this.state.title}
content={this.state.content}
- onClose={() => {this.toggleDialog(); this.setState({ name: this.props.name, description: this.props.description });}}
- onClick={() => {this.toggleDialog(); this.setState({ name: this.props.name, description: this.props.description });}}
+ onClose={() => { this.toggleDialog(); this.setState({ name: this.props.name, description: this.props.description }); }}
+ onClick={() => { this.toggleDialog(); this.setState({ name: this.props.name, description: this.props.description }); }}
button={'Abbrechen'}
>
{this.props.projectType === 'gallery' || this.state.projectType === 'gallery' ?
-
+
- :
}
+ :
}
{ this.renameWorkspace(); this.toggleDialog(); }}>Eingabe
diff --git a/src/reducers/generalReducer.js b/src/reducers/generalReducer.js
index 2d1c875..b76d9c2 100644
--- a/src/reducers/generalReducer.js
+++ b/src/reducers/generalReducer.js
@@ -1,8 +1,35 @@
-import { VISIT } from '../actions/types';
+import { VISIT, LANGUAGE, RENDERER, STATISTICS } from '../actions/types';
+
+const initialLanguage = () => {
+ if (window.localStorage.getItem('locale')) {
+ return window.localStorage.getItem('locale');
+ }
+ if (navigator.language === 'de-DE'){
+ return 'de_DE';
+ }
+ return 'en_US';
+};
+
+const initialRenderer = () => {
+ if (window.localStorage.getItem('renderer')) {
+ return window.localStorage.getItem('renderer');
+ }
+ return 'geras';
+};
+
+const initialStatistics = () => {
+ if (window.localStorage.getItem('statistics')) {
+ return JSON.parse(window.localStorage.getItem('statistics'));
+ }
+ return false;
+};
const initialState = {
- pageVisits: 0 // detect if previous URL was
+ pageVisits: 0, // detect if previous URL was
+ language: initialLanguage(),
+ renderer: initialRenderer(),
+ statistics: initialStatistics()
};
export default function(state = initialState, action){
@@ -12,6 +39,23 @@ export default function(state = initialState, action){
...state,
pageVisits: state.pageVisits += 1
};
+ case LANGUAGE:
+ return {
+ ...state,
+ language: action.payload
+ };
+ case RENDERER:
+ window.localStorage.setItem('renderer', action.payload);
+ return {
+ ...state,
+ renderer: action.payload
+ };
+ case STATISTICS:
+ window.localStorage.setItem('statistics', action.payload);
+ return {
+ ...state,
+ statistics: action.payload
+ };
default:
return state;
}