Merge branch 'master' into feat/blockly-gallery

This commit is contained in:
Mario Pesch 2020-10-20 10:49:31 +02:00 committed by GitHub
commit 0a459938a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 199 additions and 171 deletions

View File

@ -1,6 +1,7 @@
import React from 'react';
import { BrowserRouter as Router } from 'react-router-dom';
import { createBrowserHistory } from "history";
import { Provider } from 'react-redux';
import store from './store';
@ -25,12 +26,14 @@ const theme = createMuiTheme({
}
});
const customHistory = createBrowserHistory();
function App() {
return (
<ThemeProvider theme={theme}>
<Provider store={store}>
<Router>
<Router history={customHistory}>
<div className="wrapper">
<Navbar />
<Routes />

View File

@ -0,0 +1,8 @@
import { VISIT } from './types';
export const visitPage = () => (dispatch) => {
dispatch({
type: VISIT
});
};

View File

@ -27,3 +27,6 @@ export const BUILDER_CHANGE_ORDER = 'BUILDER_CHANGE_ORDER';
export const BUILDER_DELETE_PROPERTY = 'BUILDER_DELETE_PROPERTY';
export const BUILDER_ERROR = 'BUILDER_ERROR';
export const PROGRESS = 'PROGRESS';
export const VISIT = 'VISIT';

View File

@ -42,7 +42,13 @@ class BlocklySvg extends Component {
// https://github.com/google/blockly/pull/3431/files#diff-00254795773903d3c0430915a68c9521R328
cssContent += `.blocklyPath {
fill-opacity: 1;
} `;
}
.blocklyPathDark {
display: flex;
}
.blocklyPathLight {
display: flex;
} `;
var css = '<defs><style type="text/css" xmlns="http://www.w3.org/1999/xhtml"><![CDATA[' + cssContent + ']]></style></defs>';
var bbox = document.getElementsByClassName("blocklyBlockCanvas")[0].getBBox();

View File

@ -19,7 +19,7 @@ Blockly.defineBlocksWithJsonArray([ // BEGIN JSON EXTRACT
]
}
],
"output": "Boolean",
"output": Types.BOOLEAN.typeName,
"style": "logic_blocks",
"tooltip": "%{BKY_LOGIC_BOOLEAN_TOOLTIP}",
"helpUrl": "%{BKY_LOGIC_BOOLEAN_HELPURL}"
@ -32,7 +32,7 @@ Blockly.defineBlocksWithJsonArray([ // BEGIN JSON EXTRACT
{
"type": "input_value",
"name": "IF0",
"check": "Boolean"
"check": Types.getCompatibleTypes('boolean')
}
],
"message1": "%{BKY_CONTROLS_IF_MSG_THEN} %1",
@ -57,7 +57,7 @@ Blockly.defineBlocksWithJsonArray([ // BEGIN JSON EXTRACT
{
"type": "input_value",
"name": "IF0",
"check": "Boolean"
"check": Types.getCompatibleTypes('boolean')
}
],
"message1": "%{BKY_CONTROLS_IF_MSG_THEN} %1",
@ -108,7 +108,7 @@ Blockly.defineBlocksWithJsonArray([ // BEGIN JSON EXTRACT
}
],
"inputsInline": true,
"output": "Boolean",
"output": Types.BOOLEAN.typeName,
"style": "logic_blocks",
"helpUrl": "%{BKY_LOGIC_COMPARE_HELPURL}",
"extensions": ["logic_compare", "logic_op_tooltip"]
@ -121,7 +121,7 @@ Blockly.defineBlocksWithJsonArray([ // BEGIN JSON EXTRACT
{
"type": "input_value",
"name": "A",
"check": "Boolean"
"check": Types.getCompatibleTypes('boolean')
},
{
"type": "field_dropdown",
@ -134,11 +134,11 @@ Blockly.defineBlocksWithJsonArray([ // BEGIN JSON EXTRACT
{
"type": "input_value",
"name": "B",
"check": "Boolean"
"check": Types.getCompatibleTypes('boolean')
}
],
"inputsInline": true,
"output": "Boolean",
"output": Types.BOOLEAN.typeName,
"style": "logic_blocks",
"helpUrl": "%{BKY_LOGIC_OPERATION_HELPURL}",
"extensions": ["logic_op_tooltip"]
@ -151,10 +151,10 @@ Blockly.defineBlocksWithJsonArray([ // BEGIN JSON EXTRACT
{
"type": "input_value",
"name": "BOOL",
"check": "Boolean"
"check": Types.getCompatibleTypes('boolean'),
}
],
"output": "Boolean",
"output": Types.BOOLEAN.typeName,
"style": "logic_blocks",
"tooltip": "%{BKY_LOGIC_NEGATE_TOOLTIP}",
"helpUrl": "%{BKY_LOGIC_NEGATE_HELPURL}"
@ -176,7 +176,7 @@ Blockly.defineBlocksWithJsonArray([ // BEGIN JSON EXTRACT
{
"type": "input_value",
"name": "IF",
"check": "Boolean"
"check": Types.getCompatibleTypes('boolean'),
}
],
"message1": "%{BKY_LOGIC_TERNARY_IF_TRUE} %1",

View File

@ -18,7 +18,7 @@ export const CHARACTER = {
export const BOOLEAN = {
typeId: 'Boolean',
typeName: 'Boolean',
typeName: 'boolean',
typeMsgName: 'ARD_TYPE_BOOL',
}

View File

@ -11,6 +11,7 @@ import BlocklyWindow from './Blockly/BlocklyWindow';
import CodeViewer from './CodeViewer';
import TrashcanButtons from './TrashcanButtons';
import { createNameId } from 'mnemonic-id';
import HintTutorialExists from './Tutorial/HintTutorialExists';
import Grid from '@material-ui/core/Grid';
import IconButton from '@material-ui/core/IconButton';
@ -121,6 +122,7 @@ class Home extends Component {
</Grid>
: null}
</Grid>
<HintTutorialExists />
</div>
);
};

View File

@ -1,6 +1,9 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { visitPage } from '../actions/generalActions';
import { Route, Switch } from 'react-router-dom';
import { Route, Switch, withRouter } from 'react-router-dom';
import Home from './Home';
import Tutorial from './Tutorial/Tutorial';
@ -12,6 +15,10 @@ import GalleryHome from './Gallery/GalleryHome';
class Routes extends Component {
componentDidUpdate(){
this.props.visitPage();
}
render() {
return (
<div style={{ margin: '0 22px' }}>
@ -30,4 +37,8 @@ class Routes extends Component {
}
}
export default Routes;
Home.propTypes = {
visitPage: PropTypes.func.isRequired
};
export default connect(null, { visitPage })(withRouter(Routes));

View File

@ -15,7 +15,7 @@ import FormLabel from '@material-ui/core/FormLabel';
const styles = theme => ({
multiGridListTile: {
background: "#4EAF47",
background: theme.palette.primary.main,
opacity: 0.9,
height: '30px'
},

View File

@ -27,7 +27,7 @@ const styles = theme => ({
color: theme.palette.text.primary
},
multiGridListTile: {
background: "#4EAF47",
background: theme.palette.primary.main,
opacity: 0.9,
height: '30px'
},
@ -95,7 +95,7 @@ class Hardware extends Component {
>
<div>
<img src={`/media/hardware/${this.state.hardwareInfo.src}`} width="100%" alt={this.state.hardwareInfo.name} />
Weitere Informationen zur Hardware-Komponente findest du <Link href={this.state.hardwareInfo.url} color="primary">hier</Link>.
Weitere Informationen zur Hardware-Komponente findest du <Link rel="noreferrer" target="_blank" href={this.state.hardwareInfo.url} color="primary">hier</Link>.
</div>
</Dialog>

View File

@ -0,0 +1,97 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
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';
const styles = (theme) => ({
link: {
color: theme.palette.primary.main,
textDecoration: 'none',
'&:hover': {
color: theme.palette.primary.main,
textDecoration: `underline`
}
},
label: {
fontSize: '0.9rem',
color: 'grey'
}
});
class HintTutorialExists extends Component {
constructor(props){
var previousPageWasAnotherDomain = props.pageVisits === 0;
var userDoNotWantToSeeNews = window.localStorage.getItem('news') ? true : false;
console.log(userDoNotWantToSeeNews);
super(props);
this.state = {
open: userDoNotWantToSeeNews ? !userDoNotWantToSeeNews : previousPageWasAnotherDomain
};
}
toggleDialog = () => {
this.setState({ open: !this.state });
}
onChange = (e) => {
if(e.target.checked){
window.localStorage.setItem('news', e.target.checked);
}
else {
window.localStorage.deleteItem('news');
}
}
render() {
return (
<Dialog
style={{ zIndex: 9999999 }}
fullWidth
maxWidth={'sm'}
open={this.state.open}
title={'Neuigkeiten'}
content={''}
onClose={this.toggleDialog}
onClick={this.toggleDialog}
button={'Schließen'}
>
<div>
Es gibt ab jetzt Tutorials zu verschiedenen Themen. Schau mal <Link to="/tutorial" className={this.props.classes.link}>hier</Link> vorbei.
<FormControlLabel
style={{marginTop: '20px'}}
classes={{label: this.props.classes.label}}
control={
<Checkbox
size={'small'}
value={true}
checked={this.state.checked}
onChange={(e) => this.onChange(e)}
name="dialog"
color="primary"
/>
}
label={'Dialog nicht mehr anzeigen'}
/>
</div>
</Dialog>
);
};
}
HintTutorialExists.propTypes = {
pageVisits: PropTypes.number.isRequired
};
const mapStateToProps = state => ({
pageVisits: state.general.pageVisits
});
export default connect(mapStateToProps, null)(withStyles(styles, { withTheme: true })(HintTutorialExists));

View File

@ -51,6 +51,7 @@ class StepperHorizontal extends Component {
render() {
var tutorialId = this.props.currentTutorialId;
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;
@ -69,8 +70,8 @@ class StepperHorizontal extends Component {
: null}
<div className={this.props.classes.stepper}>
<Button
disabled={tutorialId === 1}
onClick={() => { this.props.history.push(`/tutorial/${tutorialId - 1}`) }}
disabled={tutorialIndex === 0}
onClick={() => { this.props.history.push(`/tutorial/${tutorials[tutorialIndex - 1].id}`) }}
>
{'<'}
</Button>
@ -81,8 +82,8 @@ class StepperHorizontal extends Component {
</div>
</Tooltip>
<Button
disabled={tutorialId + 1 > tutorials.length}
onClick={() => { this.props.history.push(`/tutorial/${tutorialId + 1}`) }}
disabled={tutorialIndex + 1 === tutorials.length}
onClick={() => { this.props.history.push(`/tutorial/${tutorials[tutorialIndex + 1].id}`) }}
>
{'>'}
</Button>
@ -95,13 +96,15 @@ class StepperHorizontal extends Component {
StepperHorizontal.propTypes = {
status: PropTypes.array.isRequired,
change: PropTypes.number.isRequired,
currentTutorialId: PropTypes.number.isRequired
currentTutorialId: PropTypes.number.isRequired,
currentTutorialIndex: PropTypes.number.isRequired
};
const mapStateToProps = state => ({
change: state.tutorial.change,
status: state.tutorial.status,
currentTutorialId: state.tutorial.currentId
currentTutorialId: state.tutorial.currentId,
currentTutorialIndex: state.tutorial.currentIndex
});
export default connect(mapStateToProps, null)(withRouter(withStyles(styles, { withTheme: true })(StepperHorizontal)));

View File

@ -156,7 +156,13 @@ class WorkspaceFunc extends Component {
// https://github.com/google/blockly/pull/3431/files#diff-00254795773903d3c0430915a68c9521R328
cssContent += `.blocklyPath {
fill-opacity: 1;
} `;
}
.blocklyPathDark {
display: flex;
}
.blocklyPathLight {
display: flex;
} `;
var css = '<defs><style type="text/css" xmlns="http://www.w3.org/1999/xhtml"><![CDATA[' + cssContent + ']]></style></defs>';

View File

@ -1,44 +0,0 @@
{
"id": 1602160884767,
"title": "Wenn-Dann Bedingungen",
"steps": [
{
"id": 1,
"type": "instruction",
"headline": "Wenn-Dann-Was?",
"text": "In diesem Tutorial lernst du die Verwendung von Wenn-Dann Bedingungen kennen. Die Wenn-Dann Bedingung ist eine der wichtigsten Kontrollstrukturen in der Programmierung und hilft dir dabei auf bestimmte Zustände einzugehen. ",
"hardware": [
"senseboxmcu",
"breadboard",
"jst-adapter",
"resistor-470ohm"
],
"requirements": [
1602160534286
]
},
{
"id": 2,
"type": "instruction",
"headline": "Aufbau der Hardware",
"text": "Verbinde die LED mit Hilfe des JST-Adapter Kabel und dem 470 Ohm Widerstand mit einem der 3 digital/analog Ports der senseBox MCU. ",
"media": {
"picture": "01_circuit.png"
}
},
{
"id": 3,
"type": "instruction",
"headline": "Die Wenn-Dann Bedingung",
"text": "Eine Wenn-Dann Bedingung kann dazu verwendet werden bestimmten Zeilen Code auszuführen, wenn eine bestimmte Bedingung erfüllt ist. \n\nwenn Bedingung dann\n Anweisung(en)\nende\n\nDas Beispiel unten zeigt dir wie eine Wenn-Dann Bedingung aufgebaut ist. Es kann zum Beispiel die Temperatur mit einem Wert verglichen werden. Ist dieser Vergleich wahr (true), dann werden die Blöcke ausgeführt, die neben \"dann\" stehen ausgeführt. Ist die Bedingung nicht erfüllt (false) dann wird einfach der Programmcode unterhalb der Wenn-Dann Bedingung ausgeführt.\n",
"xml": "<xml xmlns=\"https://developers.google.com/blockly/xml\">\n <block type=\"arduino_functions\" id=\"QWW|$jB8+*EL;}|#uA\" x=\"27\" y=\"16\">\n <statement name=\"LOOP_FUNC\">\n <block type=\"controls_if\" id=\"yu|L-MD~uP9vg@9F}Lu(\">\n <value name=\"IF0\">\n <block type=\"logic_compare\" id=\"~P6$8C+4++}u[iIr#%2-\">\n <field name=\"OP\">EQ</field>\n <value name=\"A\">\n <block type=\"sensebox_sensor_temp_hum\" id=\"Wy!eu6l0F#5ST~!$T*^W\">\n <field name=\"NAME\">Temperature</field>\n </block>\n </value>\n </block>\n </value>\n </block>\n </statement>\n </block>\n <block type=\"math_number\" id=\"n1maf$o[.I3`ce3D}]/q\" x=\"644\" y=\"180\">\n <field name=\"NUM\">0</field>\n </block>\n</xml>"
},
{
"id": 4,
"type": "task",
"headline": "Leuchten der LED auf Knopfdruck",
"text": "Lasse die LED leuchten, wenn der \"Button\" auf der senseBox MCU gedrückt wird. Den Block für den Button findest du unter \"Sensoren\".",
"xml": "<xml xmlns=\"https://developers.google.com/blockly/xml\">\n <block type=\"arduino_functions\" id=\"QWW|$jB8+*EL;}|#uA\" deletable=\"false\" x=\"27\" y=\"16\">\n <statement name=\"LOOP_FUNC\">\n <block type=\"controls_if\" id=\"^HaPX`(}uMFuMD~k1ao9\">\n <mutation elseif=\"1\"></mutation>\n <value name=\"IF0\">\n <block type=\"logic_compare\" id=\"|1,]aWRGs/Wp0}YQ{Ln{\">\n <field name=\"OP\">EQ</field>\n <value name=\"A\">\n <block type=\"sensebox_button\" id=\",@aRkh3M9K(DcYP$A(:[\">\n <field name=\"FUNCTION\">isPressed</field>\n <field name=\"PIN\">0</field>\n </block>\n </value>\n <value name=\"B\">\n <block type=\"logic_boolean\" id=\"ZjXsPgomX!cIM8bll!9;\">\n <field name=\"BOOL\">TRUE</field>\n </block>\n </value>\n </block>\n </value>\n <statement name=\"DO0\">\n <block type=\"sensebox_led\" id=\"fTE4,Kwz5s8uHaE/k:!h\">\n <field name=\"PIN\">1</field>\n <field name=\"STAT\">HIGH</field>\n </block>\n </statement>\n <value name=\"IF1\">\n <block type=\"logic_compare\" id=\"v6U9{L$*?0)r.8qG1$gn\">\n <field name=\"OP\">EQ</field>\n <value name=\"A\">\n <block type=\"sensebox_button\" id=\"yLypRfX$0DzgPYw8F/q#\">\n <field name=\"FUNCTION\">isPressed</field>\n <field name=\"PIN\">0</field>\n </block>\n </value>\n <value name=\"B\">\n <block type=\"logic_boolean\" id=\"r0c0q~2^GQo7DDjPv1.C\">\n <field name=\"BOOL\">FALSE</field>\n </block>\n </value>\n </block>\n </value>\n <statement name=\"DO1\">\n <block type=\"sensebox_led\" id=\"Zx0)_+JAGfG~b`.fYOIl\">\n <field name=\"PIN\">1</field>\n <field name=\"STAT\">LOW</field>\n </block>\n </statement>\n </block>\n </statement>\n </block>\n</xml>"
}
]
}

View File

@ -7,7 +7,7 @@
},
{
"id": "breadboard",
"name": "Steckboard",
"name": "Breadboard",
"src": "breadboard.png",
"url": "https://sensebox.github.io/books-v2/blockly/de/uebersicht/sensebox_components.html"
},

View File

@ -1,50 +0,0 @@
{
"id": 1602162097684,
"title": "Schleifen",
"steps": [
{
"id": 1,
"type": "instruction",
"headline": "Schleifen",
"text": "In diesem Tutorial wird die Verwendung von Schleifen eingeführt. Eine Schleife (auch „Wiederholung“ oder englisch loop) ist eine Kontrollstruktur in Programmiersprachen. Sie wiederholt einen Anweisungs-Block den sogenannten Schleifenrumpf oder Schleifenkörper , solange die Schleifenbedingung als Laufbedingung gültig bleibt bzw. als Abbruchbedingung nicht eintritt. Schleifen, deren Schleifenbedingung immer zur Fortsetzung führt oder die keine Schleifenbedingung haben, sind Endlosschleifen. Die Endlosschleife hast du bereits im ersten Tutorial \"Erste Schritte\" kennengelernt",
"hardware": [
"breadboard",
"jst-adapter",
"senseboxmcu",
"led",
"resistor-470ohm"
],
"requirements": [
1602160534286
]
},
{
"id": 2,
"type": "instruction",
"headline": "Verwendung von Schleifen",
"text": "Die Blöcke findest du in der Kategorie \"Schleifen\". Die einfachste Schleife, die du Verwenden kannst, ist der Block \"Wiederhole 10 mal\". Bei diesem Block kannst du die Blöcke, die eine bestimmte Zahl wiederholt werden soll einfach in den offenen Block abschnitt ziehen. ",
"xml": "<xml xmlns=\"https://developers.google.com/blockly/xml\">\n <block type=\"controls_repeat_ext\" id=\"!|`dyF$`~*!l~D[TUc4N\" x=\"38\" y=\"32\">\n <value name=\"TIMES\">\n <block type=\"math_number\" id=\"ktgQ[7pD~M{sq;r^kLuz\">\n <field name=\"NUM\">10</field>\n </block>\n </value>\n </block>\n</xml>"
},
{
"id": 3,
"type": "task",
"headline": "Verwendung von Schleifen",
"text": "Lass die LED genau 5 mal in einem Abstand von 1000 Millisekunden blinken. Anschließend soll die LED ausgeschaltet werden. ",
"xml": "<xml xmlns=\"https://developers.google.com/blockly/xml\">\n <block type=\"arduino_functions\" id=\"QWW|$jB8+*EL;}|#uA\" deletable=\"false\" x=\"18\" y=\"18\">\n <statement name=\"SETUP_FUNC\">\n <block type=\"controls_repeat_ext\" id=\"_d{J^FWUT8M?}o[/6Fpj\">\n <value name=\"TIMES\">\n <block type=\"math_number\" id=\"qao_;lzo~kE?25HM*kJ+\">\n <field name=\"NUM\">5</field>\n </block>\n </value>\n <statement name=\"DO\">\n <block type=\"sensebox_led\" id=\"A)}4:wR_79zAHUBq5?1j\">\n <field name=\"PIN\">1</field>\n <field name=\"STAT\">HIGH</field>\n <next>\n <block type=\"time_delay\" id=\"Yfn;,|wxaRhium=T[-wM\">\n <value name=\"DELAY_TIME_MILI\">\n <block type=\"math_number\" id=\"z=1f4hMm_Q~e-+Wvh,S|\">\n <field name=\"NUM\">1000</field>\n </block>\n </value>\n <next>\n <block type=\"sensebox_led\" id=\"nu2%x%_iigf]r$FJ7XEw\">\n <field name=\"PIN\">1</field>\n <field name=\"STAT\">LOW</field>\n <next>\n <block type=\"time_delay\" id=\"4@Y4E|ewWB)([vf/4Ttn\">\n <value name=\"DELAY_TIME_MILI\">\n <block type=\"math_number\" id=\"l,ZAG8;|Uv^:P5/FOjwD\">\n <field name=\"NUM\">1000</field>\n </block>\n </value>\n </block>\n </next>\n </block>\n </next>\n </block>\n </next>\n </block>\n </statement>\n </block>\n </statement>\n </block>\n</xml>"
},
{
"id": 4,
"type": "instruction",
"headline": "Schleife mit Laufzeitvariable",
"text": "Mit diesem Block lässt sich die Schleife noch genauer Steuern und beeinflussen. Hierbei wird nicht nur angegeben wie oft die Anweisungen innerhalb der Schleife wiederholt werden sondern auch welche Variable zum zählen verwendet wird und in welchen Schritten gezählt werden soll. Der Vorteil bei diesem Block ist, dass die Wert der Variable auch innerhalb der Anweisungen verwendet werden kann. So kannst zum Beispiel die Variable \"i\" verwenden um die Blinkfrequenz zu beeinflussen.",
"xml": "<xml xmlns=\"https://developers.google.com/blockly/xml\">\n <variables>\n <variable id=\")~{j#yh!vpAj!r)xZ%r`\">i</variable>\n </variables>\n <block type=\"arduino_functions\" id=\"QWW|$jB8+*EL;}|#uA\" x=\"27\" y=\"16\">\n <statement name=\"LOOP_FUNC\">\n <block type=\"controls_for\" id=\"FYj`$_+6-llMr!1pbbGa\">\n <field name=\"VAR\" id=\")~{j#yh!vpAj!r)xZ%r`\">i</field>\n <value name=\"FROM\">\n <block type=\"math_number\" id=\"d`8}:TQSpqu@$),hheqW\">\n <field name=\"NUM\">100</field>\n </block>\n </value>\n <value name=\"TO\">\n <block type=\"math_number\" id=\"SugsqbJBjnV.+wt,l*os\">\n <field name=\"NUM\">1000</field>\n </block>\n </value>\n <value name=\"BY\">\n <block type=\"math_number\" id=\"A.r{E[gVmy`GOH[/UjOd\">\n <field name=\"NUM\">100</field>\n </block>\n </value>\n <statement name=\"DO\">\n <block type=\"sensebox_led\" id=\",|)Qs}dfbh`hTL#2:vEr\">\n <field name=\"PIN\">1</field>\n <field name=\"STAT\">HIGH</field>\n <next>\n <block type=\"time_delay\" id=\"P!noJ-RN{(E{=P!1c-un\">\n <value name=\"DELAY_TIME_MILI\">\n <block type=\"variables_get_dynamic\" id=\"bd;B*4HgU:~Vb2kQ9qh.\">\n <field name=\"VAR\" id=\")~{j#yh!vpAj!r)xZ%r`\">i</field>\n </block>\n </value>\n <next>\n <block type=\"sensebox_led\" id=\"_k?%f6^b0WNYifw]yrd7\">\n <field name=\"PIN\">1</field>\n <field name=\"STAT\">LOW</field>\n <next>\n <block type=\"time_delay\" id=\"#BYOOJXBj%)0op!76)z=\">\n <value name=\"DELAY_TIME_MILI\">\n <block type=\"variables_get_dynamic\" id=\"(cg$kq?jc~Zi`6WosPN5\">\n <field name=\"VAR\" id=\")~{j#yh!vpAj!r)xZ%r`\">i</field>\n </block>\n </value>\n </block>\n </next>\n </block>\n </next>\n </block>\n </next>\n </block>\n </statement>\n </block>\n </statement>\n </block>\n</xml>"
},
{
"id": 5,
"type": "task",
"headline": "Schleifen mit Laufzeitvariable",
"text": "Verwende die Schleife mit Laufzeitvariable und beeinflusse die Blinkfrequenz mithilfe dem Wert der Variable.",
"xml": "<xml xmlns=\"https://developers.google.com/blockly/xml\">\n <variables>\n <variable id=\"*$)UUMo%aBec4cQTwHGx\">i</variable>\n </variables>\n <block type=\"arduino_functions\" id=\"QWW|$jB8+*EL;}|#uA\" deletable=\"false\" x=\"53\" y=\"10\">\n <statement name=\"LOOP_FUNC\">\n <block type=\"controls_for\" id=\"K(eQur,H3CCpZ4aKVehO\">\n <field name=\"VAR\" id=\"*$)UUMo%aBec4cQTwHGx\">i</field>\n <value name=\"FROM\">\n <block type=\"math_number\" id=\"J^UJb^1-SukkH7yBbynj\">\n <field name=\"NUM\">100</field>\n </block>\n </value>\n <value name=\"TO\">\n <block type=\"math_number\" id=\"azP7sh9f,v$9VH[.9BCh\">\n <field name=\"NUM\">1000</field>\n </block>\n </value>\n <value name=\"BY\">\n <block type=\"math_number\" id=\"#j`dag~sK!]D#{_;._)%\">\n <field name=\"NUM\">100</field>\n </block>\n </value>\n <statement name=\"DO\">\n <block type=\"sensebox_led\" id=\"H6+{(4h(}a[yr5w,f(`,\">\n <field name=\"PIN\">1</field>\n <field name=\"STAT\">HIGH</field>\n <next>\n <block type=\"time_delay\" id=\"vPfaX^j~7;YwT+A!y@**\">\n <value name=\"DELAY_TIME_MILI\">\n <block type=\"variables_get_dynamic\" id=\"1}5O.el5^EHJCM`,oa4-\">\n <field name=\"VAR\" id=\"*$)UUMo%aBec4cQTwHGx\">i</field>\n </block>\n </value>\n <next>\n <block type=\"sensebox_led\" id=\"TRn{}$-@^eXI?eGfWJ/{\">\n <field name=\"PIN\">1</field>\n <field name=\"STAT\">LOW</field>\n <next>\n <block type=\"time_delay\" id=\"x@]F,29zp}87PA|2+eoJ\">\n <value name=\"DELAY_TIME_MILI\">\n <block type=\"variables_get_dynamic\" id=\"WF.bP/9w[WlFoF*2;*{G\">\n <field name=\"VAR\" id=\"*$)UUMo%aBec4cQTwHGx\">i</field>\n </block>\n </value>\n </block>\n </next>\n </block>\n </next>\n </block>\n </next>\n </block>\n </statement>\n </block>\n </statement>\n </block>\n <block type=\"math_number\" id=\"!42y97D|+Vi9*DKE^5p`\" disabled=\"true\" x=\"198\" y=\"184\">\n <field name=\"NUM\">1000</field>\n </block>\n</xml>"
}
]
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"id":1602160884767,"title":"Wenn-Dann Bedingungen","steps":[{"id":1,"type":"instruction","headline":"Wenn-Dann-Was?","text":"In diesem Tutorial lernst du die Verwendung von Wenn-Dann Bedingungen kennen. Die Wenn-Dann Bedingung ist eine der wichtigsten Kontrollstrukturen in der Programmierung und hilft dir dabei auf bestimmte Zustände einzugehen. ","hardware":["senseboxmcu","breadboard","jst-adapter","resistor-470ohm"],"requirements":[1602160534286]},{"id":2,"type":"instruction","headline":"Aufbau der Hardware","text":"Verbinde die LED mit Hilfe des JST-Adapter Kabel und dem 470 Ohm Widerstand mit einem der 3 digital/analog Ports der senseBox MCU. ","media":{"picture":"01_circuit.png"}},{"id":3,"type":"instruction","headline":"Die Wenn-Dann Bedingung","text":"Eine Wenn-Dann Bedingung kann dazu verwendet werden bestimmten Zeilen Code auszuführen, wenn eine bestimmte Bedingung erfüllt ist. \n\nwenn Bedingung dann\n Anweisung(en)\nende\n\nDas Beispiel unten zeigt dir wie eine Wenn-Dann Bedingung aufgebaut ist. Es kann zum Beispiel die Temperatur mit einem Wert verglichen werden. Ist dieser Vergleich wahr (true), dann werden die Blöcke ausgeführt, die neben \"dann\" stehen ausgeführt. Ist die Bedingung nicht erfüllt (false) dann wird einfach der Programmcode unterhalb der Wenn-Dann Bedingung ausgeführt.\n","xml":"<xml xmlns=\"https://developers.google.com/blockly/xml\">\n <block type=\"arduino_functions\" id=\"QWW|$jB8+*EL;}|#uA\" x=\"27\" y=\"16\">\n <statement name=\"LOOP_FUNC\">\n <block type=\"controls_if\" id=\"yu|L-MD~uP9vg@9F}Lu(\">\n <value name=\"IF0\">\n <block type=\"logic_compare\" id=\"~P6$8C+4++}u[iIr#%2-\">\n <field name=\"OP\">EQ</field>\n <value name=\"A\">\n <block type=\"sensebox_sensor_temp_hum\" id=\"Wy!eu6l0F#5ST~!$T*^W\">\n <field name=\"NAME\">Temperature</field>\n </block>\n </value>\n <value name=\"B\">\n <block type=\"math_number\" id=\"n1maf$o[.I3`ce3D}]/q\">\n <field name=\"NUM\">0</field>\n </block>\n </value>\n </block>\n </value>\n </block>\n </statement>\n </block>\n</xml>"},{"id":4,"type":"task","headline":"Leuchten der LED auf Knopfdruck","text":"Lasse die LED leuchten, wenn der \"Button\" auf der senseBox MCU gedrückt wird. Den Block für den Button findest du unter \"Sensoren\".","xml":"<xml xmlns=\"https://developers.google.com/blockly/xml\">\n <block type=\"arduino_functions\" id=\"QWW|$jB8+*EL;}|#uA\" deletable=\"false\" x=\"27\" y=\"16\">\n <statement name=\"LOOP_FUNC\">\n <block type=\"controls_if\" id=\"^HaPX`(}uMFuMD~k1ao9\">\n <mutation elseif=\"1\"></mutation>\n <value name=\"IF0\">\n <block type=\"logic_compare\" id=\"|1,]aWRGs/Wp0}YQ{Ln{\">\n <field name=\"OP\">EQ</field>\n <value name=\"A\">\n <block type=\"sensebox_button\" id=\",@aRkh3M9K(DcYP$A(:[\">\n <field name=\"FUNCTION\">isPressed</field>\n <field name=\"PIN\">0</field>\n </block>\n </value>\n <value name=\"B\">\n <block type=\"logic_boolean\" id=\"ZjXsPgomX!cIM8bll!9;\">\n <field name=\"BOOL\">TRUE</field>\n </block>\n </value>\n </block>\n </value>\n <statement name=\"DO0\">\n <block type=\"sensebox_led\" id=\"fTE4,Kwz5s8uHaE/k:!h\">\n <field name=\"PIN\">1</field>\n <field name=\"STAT\">HIGH</field>\n </block>\n </statement>\n <value name=\"IF1\">\n <block type=\"logic_compare\" id=\"v6U9{L$*?0)r.8qG1$gn\">\n <field name=\"OP\">EQ</field>\n <value name=\"A\">\n <block type=\"sensebox_button\" id=\"yLypRfX$0DzgPYw8F/q#\">\n <field name=\"FUNCTION\">isPressed</field>\n <field name=\"PIN\">0</field>\n </block>\n </value>\n <value name=\"B\">\n <block type=\"logic_boolean\" id=\"r0c0q~2^GQo7DDjPv1.C\">\n <field name=\"BOOL\">FALSE</field>\n </block>\n </value>\n </block>\n </value>\n <statement name=\"DO1\">\n <block type=\"sensebox_led\" id=\"Zx0)_+JAGfG~b`.fYOIl\">\n <field name=\"PIN\">1</field>\n <field name=\"STAT\">LOW</field>\n </block>\n </statement>\n </block>\n </statement>\n </block>\n</xml>"}]}

View File

@ -1,10 +1,9 @@
let tutorials = [
require('./ErsteSchritte.json'),
require('./loops_01.json'),
require('./Wenn-DannBedingungen.json'),
require('./variablen_01.json'),
require('./AnzeigeVonMesswertenAufDemDisplay.json')
require('./tutorial/ErsteSchritte.json'),
require('./tutorial/Schleifen.json'),
require('./tutorial/Wenn-DannBedingungen.json'),
require('./tutorial/VerwendungVonVariablen.json'),
require('./tutorial/AnzeigeVonMesswertenAufDemDisplay.json')
]
module.exports = tutorials;
module.exports = tutorials;

View File

@ -1,41 +0,0 @@
{
"id": 1602162172424,
"title": "Verwendung von Variablen",
"steps": [
{
"id": 1,
"type": "instruction",
"headline": "Variablen",
"text": "Variablen, auch Platzhalter genannt, werden in der Informatik für verschiedene Dinge genutzt. Sie sind eine Art Kiste, die mit einem Namen versehen ist. In dieser Kiste kannst du verschiedene Dinge hinterlegen (z.B. Zahlen und Texte) und diese später wieder abrufen. ",
"hardware": [
"senseboxmcu",
"oled",
"jst-jst",
"hdc1080"
],
"requirements": [
1602160534286
]
},
{
"id": 2,
"type": "instruction",
"headline": "Aufbau der Hardware",
"text": "Verbinde das Display und den Temperatur- und Luftfeuchtigkeitssensor jeweils mit einem JST-JST Kabel mit einem der 5 I2C Ports auf der senseBox MCU."
},
{
"id": 3,
"type": "instruction",
"headline": "Variablen in Blockly",
"text": "Variablen können ihren Wert im Laufe des Programmes verändern, sodass du zum Beispiel der Variable „Temperatur“ immer den aktuell gemessenen Temperaturwert zuweist. Eine Variablen besitzt immer einer bestimmten Datentyp. Der Datentyp gibt im Endeffekt an, wie groß die Kiste ist und wie der Wert aussehen kann, der in der Variable gespeichert werden kann. \n\nVariablen - Datentypen\nJe nachdem, was du in einer Variable speichern möchtest, musst du den richten Datentyp auswählen.\nZeichen: Für einzelne Textzeichen\nText: Für ganze Wörter oder Sätze\nZahl: Für Zahlen von -32768 bis +32768\nGroße Zahl: Für Zahlen von -2147483648 bis\n +2147483648\nDezimalzahl: Für Kommazahlen (z.B. 25,3)",
"xml": "<xml xmlns=\"https://developers.google.com/blockly/xml\">\n <variables>\n <variable type=\"float\" id=\"s/vc$u-EyvVr.Nj(m}Qu\">Temperatur</variable>\n </variables>\n <block type=\"arduino_functions\" id=\"QWW|$jB8+*EL;}|#uA\" x=\"27\" y=\"16\">\n <statement name=\"SETUP_FUNC\">\n <block type=\"sensebox_display_beginDisplay\" id=\"`tj@e,u63(d3fs/K71`A\"></block>\n </statement>\n <statement name=\"LOOP_FUNC\">\n <block type=\"variables_set_dynamic\" id=\"9.`Dj,eU7L15ZD{o2c^{\">\n <field name=\"VAR\" id=\"s/vc$u-EyvVr.Nj(m}Qu\" variabletype=\"float\">Temperatur</field>\n <value name=\"VALUE\">\n <block type=\"sensebox_sensor_temp_hum\" id=\"Ml7-3urP[?9L4k71u5/f\">\n <field name=\"NAME\">Temperature</field>\n </block>\n </value>\n <next>\n <block type=\"sensebox_display_show\" id=\"J[dD~4AnHRXYq3qK5^{z\">\n <statement name=\"SHOW\">\n <block type=\"sensebox_display_printDisplay\" id=\"sg25UA3mp72*zt_.hgR%\">\n <field name=\"COLOR\">WHITE,BLACK</field>\n <field name=\"SIZE\">1</field>\n <field name=\"X\">0</field>\n <field name=\"Y\">0</field>\n </block>\n </statement>\n </block>\n </next>\n </block>\n </statement>\n </block>\n <block type=\"variables_get_dynamic\" id=\"Pi0a=LwOd]Qx1}q[QljS\" x=\"252\" y=\"336\">\n <field name=\"VAR\" id=\"s/vc$u-EyvVr.Nj(m}Qu\" variabletype=\"float\">Temperatur</field>\n </block>\n</xml>"
},
{
"id": 4,
"type": "task",
"headline": "Aufgabe 1:",
"text": "Erste 2 Variablen vom Typ \"Kommazahl\" und weise die Werte für Temperatur und Luftfeuchtigkeit zu. Lasse anschließend den Wert der Variablen auf dem Display anzeigen.",
"xml": "<xml xmlns=\"https://developers.google.com/blockly/xml\">\n <variables>\n <variable type=\"float\" id=\";%_Xz2^W|D@`pj|28,!5\">Temperatur</variable>\n <variable type=\"float\" id=\"[EbZeJmVDy_yf%nn}kg`\">Luftfeuchte</variable>\n </variables>\n <block type=\"arduino_functions\" id=\"QWW|$jB8+*EL;}|#uA\" deletable=\"false\" x=\"27\" y=\"16\">\n <statement name=\"SETUP_FUNC\">\n <block type=\"sensebox_display_beginDisplay\" id=\"#v)|Z-SGAvCfh+tW*u:b\"></block>\n </statement>\n <statement name=\"LOOP_FUNC\">\n <block type=\"variables_set_dynamic\" id=\"4(3O[5o69|]D[1(`OS77\">\n <field name=\"VAR\" id=\";%_Xz2^W|D@`pj|28,!5\" variabletype=\"float\">Temperatur</field>\n <value name=\"VALUE\">\n <block type=\"sensebox_sensor_temp_hum\" id=\"lqo)Q_WfPH/)#n?Kejw9\">\n <field name=\"NAME\">Temperature</field>\n </block>\n </value>\n <next>\n <block type=\"variables_set_dynamic\" id=\"wZ([1QpBf,W-+ML8$yE^\">\n <field name=\"VAR\" id=\"[EbZeJmVDy_yf%nn}kg`\" variabletype=\"float\">Luftfeuchte</field>\n <value name=\"VALUE\">\n <block type=\"sensebox_sensor_temp_hum\" id=\"N@rK(BhH:*:,7?gd0znv\">\n <field name=\"NAME\">Temperature</field>\n </block>\n </value>\n <next>\n <block type=\"sensebox_display_show\" id=\")HB9?-!GebOtxFJ*UF9:\">\n <statement name=\"SHOW\">\n <block type=\"sensebox_display_printDisplay\" id=\"U90y}?~Cvp?uS2KfL#Ph\">\n <field name=\"COLOR\">WHITE,BLACK</field>\n <field name=\"SIZE\">1</field>\n <field name=\"X\">0</field>\n <field name=\"Y\">0</field>\n <value name=\"printDisplay\">\n <block type=\"variables_get_dynamic\" id=\"+.p4#smC?kl[1{cjt70R\">\n <field name=\"VAR\" id=\"[EbZeJmVDy_yf%nn}kg`\" variabletype=\"float\">Luftfeuchte</field>\n </block>\n </value>\n <next>\n <block type=\"sensebox_display_printDisplay\" id=\"GfS)4y,Y7[nm[KUW*uGL\">\n <field name=\"COLOR\">WHITE,BLACK</field>\n <field name=\"SIZE\">1</field>\n <field name=\"X\">0</field>\n <field name=\"Y\">20</field>\n <value name=\"printDisplay\">\n <block type=\"variables_get_dynamic\" id=\"wWCpBCPp9i%M13l9H^Et\">\n <field name=\"VAR\" id=\";%_Xz2^W|D@`pj|28,!5\" variabletype=\"float\">Temperatur</field>\n </block>\n </value>\n </block>\n </next>\n </block>\n </statement>\n <next>\n <block type=\"sensebox_display_clearDisplay\" id=\"E%fqa!5WcG$MDFM..7)G\"></block>\n </next>\n </block>\n </next>\n </block>\n </next>\n </block>\n </statement>\n </block>\n</xml>"
}
]
}

View File

@ -0,0 +1,18 @@
import { VISIT } from '../actions/types';
const initialState = {
pageVisits: 0 // detect if previous URL was
};
export default function(state = initialState, action){
switch(action.type){
case VISIT:
return {
...state,
pageVisits: state.pageVisits += 1
};
default:
return state;
}
}

View File

@ -2,9 +2,11 @@ import { combineReducers } from 'redux';
import workspaceReducer from './workspaceReducer';
import tutorialReducer from './tutorialReducer';
import tutorialBuilderReducer from './tutorialBuilderReducer';
import generalReducer from './generalReducer';
export default combineReducers({
workspace: workspaceReducer,
tutorial: tutorialReducer,
builder: tutorialBuilderReducer
builder: tutorialBuilderReducer,
general: generalReducer
});

View File

@ -41,6 +41,7 @@ const initialStatus = () => {
const initialState = {
status: initialStatus(),
currentId: null,
currentIndex: null,
activeStep: 0,
change: 0
};
@ -64,7 +65,8 @@ export default function (state = initialState, action) {
case TUTORIAL_ID:
return {
...state,
currentId: action.payload
currentId: action.payload,
currentIndex: tutorials.findIndex(tutorial => tutorial.id === action.payload)
}
case TUTORIAL_STEP:
return {