add generalReducer to store settings

This commit is contained in:
Delucse 2020-12-14 13:06:55 +01:00
parent 7d1d2409e4
commit e52e3943c1
14 changed files with 360 additions and 170 deletions

View File

@ -11,10 +11,7 @@ import './App.css';
import { ThemeProvider, createMuiTheme } from '@material-ui/core/styles';
import Navbar from './components/Navbar';
import Footer from './components/Footer';
import Routes from './components/Route/Routes';
import Cookies from './components/Cookies';
import Content from './components/Content';
const theme = createMuiTheme({
palette: {
@ -43,12 +40,7 @@ class App extends Component {
<ThemeProvider theme={theme}>
<Provider store={store}>
<Router history={customHistory}>
<div className="wrapper">
<Navbar />
<Routes />
<Cookies />
<Footer />
</div>
<Content />
</Router>
</Provider>
</ThemeProvider>

View File

@ -1,4 +1,4 @@
import { VISIT } from './types';
import { VISIT, LANGUAGE, RENDERER, STATISTICS } from './types';
export const visitPage = () => (dispatch) => {
@ -6,3 +6,24 @@ export const visitPage = () => (dispatch) => {
type: VISIT
});
};
export const setLanguage = (language) => (dispatch) => {
dispatch({
type: LANGUAGE,
payload: language
});
};
export const setRenderer = (renderer) => (dispatch) => {
dispatch({
type: RENDERER,
payload: renderer
});
};
export const setStatistics = (showStatistics) => (dispatch) => {
dispatch({
type: STATISTICS,
payload: showStatistics
});
};

View File

@ -46,6 +46,9 @@ export const PROGRESS = 'PROGRESS';
export const VISIT = 'VISIT';
export const LANGUAGE = 'LANGUAGE';
export const RENDERER = 'RENDERER';
export const STATISTICS = 'STATISTICS';
// messages
export const GET_ERRORS = 'GET_ERRORS';

View File

@ -18,26 +18,21 @@ class BlocklyWindow extends Component {
constructor(props) {
super(props);
this.simpleWorkspace = React.createRef();
var locale = window.localStorage.getItem('locale');
this.state = {
renderer: window.localStorage.getItem('renderer'),
};
if (locale === null) {
if (navigator.language === 'de-DE') {
locale = 'de';
} else {
locale = 'en';
}
}
if (locale === 'de') {
// if (locale === null) {
// if (navigator.language === 'de-DE') {
// locale = 'de';
// } else {
// locale = 'en';
// }
// }
if (this.props.language === 'de') {
Blockly.setLocale(De);
} else if (locale === 'en') {
} else if (this.props.language === 'en') {
Blockly.setLocale(En);
}
}
componentDidMount() {
const workspace = Blockly.getMainWorkspace();
this.props.onChangeWorkspace({});
this.props.clearStats();
@ -72,7 +67,7 @@ class BlocklyWindow extends Component {
style={this.props.svg ? { height: 0 } : this.props.blocklyCSS}
readOnly={this.props.readOnly !== undefined ? this.props.readOnly : false}
trashcan={this.props.trashcan !== undefined ? this.props.trashcan : true}
renderer={this.state.renderer}
renderer={this.props.renderer}
zoom={{ // https://developers.google.com/blockly/guides/configure/web/zoom
controls: this.props.zoomControls !== undefined ? this.props.zoomControls : true,
wheel: false,
@ -106,8 +101,14 @@ class BlocklyWindow extends Component {
BlocklyWindow.propTypes = {
onChangeWorkspace: PropTypes.func.isRequired,
clearStats: PropTypes.func.isRequired
clearStats: PropTypes.func.isRequired,
renderer: PropTypes.string.isRequired,
language: PropTypes.string.isRequired
};
const mapStateToProps = state => ({
renderer: state.general.renderer,
language: state.general.language
});
export default connect(null, { onChangeWorkspace, clearStats })(BlocklyWindow);
export default connect(mapStateToProps, { onChangeWorkspace, clearStats })(BlocklyWindow);

View File

@ -804,7 +804,7 @@ Blockly.Msg.senseBox_mqtt_publish = "Sende an Feed/Topic";
/**
* Typed Variable Modal
*
*
*/
@ -835,7 +835,7 @@ Blockly.Msg.toolbox_variables = "Variablen";
/**
* Tooltips
*
*
*/
Blockly.Msg.tooltip_compile_code = "Code kompilieren"
@ -863,7 +863,7 @@ Blockly.Msg.tooltip_project_title = "Titel des Projektes"
/**
* Messages
*
*
*/
Blockly.Msg.messages_delete_project_failed = "Fehler beim Löschen des Projektes. Versuche es noch einmal."
@ -895,7 +895,7 @@ Blockly.Msg.renamedialog_text = "Bitte gib einen Namen für das Projekt ein und
/**
* Compile Dialog
*
*
*/
Blockly.Msg.compiledialog_headline = "Fehler"
@ -903,7 +903,7 @@ Blockly.Msg.compiledialog_text = "Beim kompilieren ist ein Fehler aufgetreten.
/**
* Buttons
*
*
*/
Blockly.Msg.button_cancel = "Abbrechen";
@ -915,7 +915,7 @@ Blockly.Msg.button_back = "Zurück"
/**
*
*
*/
Blockly.Msg.filename = "Dateiname";
@ -926,9 +926,15 @@ Blockly.Msg.projectname = "Projektname";
*/
Blockly.Msg.settings_head = "Einstellungen"
Blockly.Msg.settings_language = "Sprache"
Blockly.Msg.settings_language_text = "Auswahl der Sprache gilt für die gesamte Anwendung. Es kann zwischen Deutsch und Englisch unterschieden werden."
Blockly.Msg.settings_language_de = "Deutsch"
Blockly.Msg.settings_language_en = "Englisch"
Blockly.Msg.settings_renderer_text = "Der Renderer bestimmt das aussehen der Blöcke"
Blockly.Msg.settings_renderer = "Renderer"
Blockly.Msg.settings_renderer_text = "Der eingestellte Renderer bestimmt das Aussehen der Blöcke. Es kann zwischen 'Geras' und 'Zelos' unterschieden werden, wobei 'Zelos' insbesondere für eine Touch-Anwendung geeignet ist."
Blockly.Msg.settings_statistics = "Statistiken"
Blockly.Msg.settings_statistics_text = "Die Anzeige von Statistiken zur Nutzung der Blöcke oberhalb der Arbeitsfläche kann ein- oder ausgeblendet werden."
Blockly.Msg.settings_statistics_on = "An"
Blockly.Msg.settings_statistics_off = "Aus"
/**
* 404

View File

@ -805,7 +805,7 @@ Blockly.Msg.toolbox_variables = "Variables";
/**
* Tooltips
*
*
*/
Blockly.Msg.tooltip_compile_code = "Compile Code"
@ -834,7 +834,7 @@ Blockly.Msg.renamedialog_text = "Please enter a name for the project and confirm
/**
* Compile Dialog
*
*
*/
Blockly.Msg.compiledialog_headline = "Error"
@ -844,7 +844,7 @@ Blockly.Msg.compiledialog_text = "While compiling an error occured. Please check
/**
* Buttons
*
*
*/
Blockly.Msg.button_cancel = "Cancel";
@ -855,12 +855,26 @@ Blockly.Msg.button_create_variableCreate = "Create Variable";
/**
*
*
*/
Blockly.Msg.filename = "Filename";
Blockly.Msg.projectname = "Projectname";
/**
* Settings
*/
Blockly.Msg.settings_head = "Settings"
Blockly.Msg.settings_language = "Language"
Blockly.Msg.settings_language_text = "Selection of the language applies to the entire application. A distinction can be made between German and English."
Blockly.Msg.settings_language_de = "German"
Blockly.Msg.settings_language_en = "English"
Blockly.Msg.settings_renderer = "Renderer"
Blockly.Msg.settings_renderer_text = "The selected renderer determines the appearance of the blocks. A distinction can be made between 'Geras' and 'Zelos', whereby 'Zelos' is particularly suitable for a touch application."
Blockly.Msg.settings_statistics = "Statistics"
Blockly.Msg.settings_statistics_text = "The display of statistics on the usage of the blocks above the workspace can be shown or hidden."
Blockly.Msg.settings_statistics_on = "On"
Blockly.Msg.settings_statistics_off = "Off"

54
src/components/Content.js Normal file
View File

@ -0,0 +1,54 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import * as Blockly from 'blockly/core';
import { De } from './Blockly/msg/de';
import { En } from './Blockly/msg/en';
import Navbar from './Navbar';
import Footer from './Footer';
import Routes from './Route/Routes';
import Cookies from './Cookies';
class Content extends Component {
componentDidMount() {
if (this.props.language === 'de') {
Blockly.setLocale(De);
} else if (this.props.language === 'en') {
Blockly.setLocale(En);
}
}
componentDidUpdate(props){
if(props.language !== this.props.language){
if (this.props.language === 'de') {
Blockly.setLocale(De);
} else if (this.props.language === 'en') {
Blockly.setLocale(En);
}
}
}
render() {
return (
<div className="wrapper">
<Navbar />
<Routes />
<Cookies />
<Footer />
</div>
);
}
}
Content.propTypes = {
language: PropTypes.string.isRequired
};
const mapStateToProps = state => ({
language: state.general.language
});
export default connect(mapStateToProps, null)(Content);

View File

@ -48,7 +48,6 @@ class Home extends Component {
state = {
codeOn: false,
stats: window.localStorage.getItem('stats'),
snackbar: false,
type: '',
key: '',
@ -91,7 +90,7 @@ class Home extends Component {
render() {
return (
<div>
{this.state.stats ?
{this.props.statistics ?
<div style={{ float: 'left', height: '40px', position: 'relative' }}><WorkspaceStats /></div>
: null
}
@ -136,11 +135,13 @@ class Home extends Component {
Home.propTypes = {
clearStats: PropTypes.func.isRequired,
workspaceName: PropTypes.func.isRequired,
message: PropTypes.object.isRequired
message: PropTypes.object.isRequired,
statistics: PropTypes.bool.isRequired
};
const mapStateToProps = state => ({
message: state.message
message: state.message,
statistics: state.general.statistics
});

View File

@ -9,6 +9,13 @@ import Typography from '@material-ui/core/Typography';
import * as Blockly from 'blockly'
class NotFound extends Component {
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 (
<div>

View File

@ -1,44 +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 * as Blockly from 'blockly/core';
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 (
<div>
<FormControl className={classes.formControl}>
<InputLabel id="demo-simple-select-label">{Blockly.Msg.settings_language}</InputLabel>
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
value={lang}
onChange={handleChange}
>
<MenuItem value={'de'}>Deutsch</MenuItem>
<MenuItem value={'en'}>Englisch</MenuItem>
</Select>
</FormControl>
</div>
render(){
return(
<div>
<Typography style={{fontWeight: 'bold'}}>{Blockly.Msg.settings_language}</Typography>
<FormHelperText style={{color: 'black', lineHeight: 1.3, marginBottom: '8px'}}>{Blockly.Msg.settings_language_text}</FormHelperText>
<FormControl>
<InputLabel id="demo-simple-select-label">{Blockly.Msg.settings_language}</InputLabel>
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
value={this.props.language}
onChange={this.handleChange}
>
<MenuItem value={'de'}>{Blockly.Msg.settings_language_de}</MenuItem>
<MenuItem value={'en'}>{Blockly.Msg.settings_language_en}</MenuItem>
</Select>
</FormControl>
</div>
);
}
}
LanguageSelector.propTypes = {
setLanguage: PropTypes.func.isRequired,
language: PropTypes.string.isRequired
};
const mapStateToProps = state => ({
language: state.general.language
});
export default connect(mapStateToProps, { setLanguage })(LanguageSelector);

View File

@ -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 * as Blockly from 'blockly/core'
const useStyles = makeStyles((theme) => ({
formControl: {
margin: theme.spacing(1),
minWidth: 400,
},
selectEmpty: {
marginTop: theme.spacing(2),
},
}));
import Typography from '@material-ui/core/Typography';
import FormHelperText from '@material-ui/core/FormHelperText';
export default function RenderSelector() {
const classes = useStyles();
const [renderer, setRenderer] = React.useState(window.localStorage.getItem('renderer'));
const handleChange = (event) => {
setRenderer(event.target.value);
window.localStorage.setItem('renderer', event.target.value);
};
class RenderSelector extends Component {
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 (
<div>
<FormControl className={classes.formControl}>
<InputLabel id="demo-simple-select-label">Renderer</InputLabel>
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
value={renderer}
onChange={handleChange}
>
<MenuItem value={'geras'}>Geras</MenuItem>
<MenuItem value={'zelos'}>Zelos</MenuItem>
</Select>
</FormControl>
<p>{Blockly.Msg.settings_renderer_text}</p>
</div>
<div>
<Typography style={{fontWeight: 'bold'}}>{Blockly.Msg.settings_renderer}</Typography>
<FormHelperText style={{color: 'black', lineHeight: 1.3, marginBottom: '8px'}}>{Blockly.Msg.settings_renderer_text}</FormHelperText>
<FormControl>
<InputLabel id="demo-simple-select-label">{Blockly.Msg.settings_renderer}</InputLabel>
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
value={this.props.renderer}
onChange={(e) => this.props.setRenderer(e.target.value)}
>
<MenuItem value={'geras'}>Geras</MenuItem>
<MenuItem value={'zelos'}>Zelos</MenuItem>
</Select>
</FormControl>
</div>
);
}
}
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);

View File

@ -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 * as Blockly from 'blockly'
import Button from '@material-ui/core/Button';
import Paper from '@material-ui/core/Paper';
class Settings extends Component {
render() {
return (
<div>
<Typography variant='h4' style={{ marginBottom: '5px' }}>{Blockly.Msg.settings_head}</Typography>
<LanguageSelector />
<RenderSelector />
<StatsSelector />
<Button
style={{ marginTop: '20px' }}
variant="contained"
color="primary"
onClick={() => { this.props.history.push('/') }}
>
{Blockly.Msg.button_back}
</Button>
</div>
);
};
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 (
<div>
<Breadcrumbs content={[{ link: this.props.location.pathname, title: Blockly.Msg.settings_head }]} />
<h1>{Blockly.Msg.settings_head}</h1>
<Paper style={{margin: '10px 0px', padding: '10px'}}>
<LanguageSelector />
</Paper>
<Paper style={{margin: '10px 0px', padding: '10px'}}>
<RenderSelector />
</Paper>
<Paper style={{margin: '10px 0px', padding: '10px'}}>
<StatsSelector />
</Paper>
<Button
style={{ marginTop: '10px' }}
variant="contained"
color="primary"
onClick={this.props.pageVisits > 0 ? () => this.props.history.goBack() : () => this.props.history.push('/')}
>
{Blockly.Msg.button_back}
</Button>
</div>
);
};
}
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));

View File

@ -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 (
<div>
<FormControl className={classes.formControl}>
<InputLabel id="demo-simple-select-label">Statistiken</InputLabel>
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
value={stats}
onChange={handleChange}
>
<MenuItem value={true}>On</MenuItem>
<MenuItem value={false}>Off</MenuItem>
</Select>
</FormControl>
<p>Schaltet die Statistiken Oberhalb der Arbeitsfläche ein bzw. aus</p>
</div>
<div>
<Typography style={{fontWeight: 'bold'}}>{Blockly.Msg.settings_statistics}</Typography>
<FormHelperText style={{color: 'black', lineHeight: 1.3, marginBottom: '8px'}}>{Blockly.Msg.settings_statistics_text}</FormHelperText>
<FormControl>
<InputLabel id="demo-simple-select-label">{Blockly.Msg.settings_statistics}</InputLabel>
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
value={this.props.statistics}
onChange={(e) => this.props.setStatistics(e.target.value)}
>
<MenuItem value={true}>{Blockly.Msg.settings_statistics_on}</MenuItem>
<MenuItem value={false}>{Blockly.Msg.settings_statistics_off}</MenuItem>
</Select>
</FormControl>
</div>
);
}
}
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);

View File

@ -1,8 +1,11 @@
import { VISIT } from '../actions/types';
import { VISIT, LANGUAGE, RENDERER, STATISTICS } from '../actions/types';
const initialState = {
pageVisits: 0 // detect if previous URL was
pageVisits: 0, // detect if previous URL was
language: 'de',
renderer: window.localStorage.getItem('renderer') || 'geras',
statistics: window.localStorage.getItem('statistics') === 'true' ? true : window.localStorage.getItem('statistics') === 'false' ? false : false
};
export default function(state = initialState, action){
@ -12,6 +15,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;
}