diff --git a/src/App.js b/src/App.js index 50afe39..35f9218 100644 --- a/src/App.js +++ b/src/App.js @@ -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 ( - +
diff --git a/src/actions/generalActions.js b/src/actions/generalActions.js new file mode 100644 index 0000000..6585a9a --- /dev/null +++ b/src/actions/generalActions.js @@ -0,0 +1,8 @@ +import { VISIT } from './types'; + + +export const visitPage = () => (dispatch) => { + dispatch({ + type: VISIT + }); +}; diff --git a/src/actions/types.js b/src/actions/types.js index 0a1dc72..c65c9ec 100644 --- a/src/actions/types.js +++ b/src/actions/types.js @@ -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'; diff --git a/src/components/Blockly/BlocklySvg.js b/src/components/Blockly/BlocklySvg.js index f20ce0c..84a4c00 100644 --- a/src/components/Blockly/BlocklySvg.js +++ b/src/components/Blockly/BlocklySvg.js @@ -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 = ''; var bbox = document.getElementsByClassName("blocklyBlockCanvas")[0].getBBox(); diff --git a/src/components/Blockly/blocks/logic.js b/src/components/Blockly/blocks/logic.js index 5feb5b7..75839e6 100644 --- a/src/components/Blockly/blocks/logic.js +++ b/src/components/Blockly/blocks/logic.js @@ -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", diff --git a/src/components/Blockly/helpers/types.js b/src/components/Blockly/helpers/types.js index 48def90..9abdd85 100644 --- a/src/components/Blockly/helpers/types.js +++ b/src/components/Blockly/helpers/types.js @@ -18,7 +18,7 @@ export const CHARACTER = { export const BOOLEAN = { typeId: 'Boolean', - typeName: 'Boolean', + typeName: 'boolean', typeMsgName: 'ARD_TYPE_BOOL', } diff --git a/src/components/Home.js b/src/components/Home.js index 9b4b155..f54b129 100644 --- a/src/components/Home.js +++ b/src/components/Home.js @@ -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 { : null} +
); }; diff --git a/src/components/Routes.js b/src/components/Routes.js index f312005..a12ef2b 100644 --- a/src/components/Routes.js +++ b/src/components/Routes.js @@ -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 (
@@ -30,4 +37,8 @@ class Routes extends Component { } } -export default Routes; +Home.propTypes = { + visitPage: PropTypes.func.isRequired +}; + +export default connect(null, { visitPage })(withRouter(Routes)); diff --git a/src/components/Tutorial/Builder/Hardware.js b/src/components/Tutorial/Builder/Hardware.js index b22b0d0..a47a24d 100644 --- a/src/components/Tutorial/Builder/Hardware.js +++ b/src/components/Tutorial/Builder/Hardware.js @@ -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' }, diff --git a/src/components/Tutorial/Hardware.js b/src/components/Tutorial/Hardware.js index 001ff9e..35602bb 100644 --- a/src/components/Tutorial/Hardware.js +++ b/src/components/Tutorial/Hardware.js @@ -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 { >
{this.state.hardwareInfo.name} - Weitere Informationen zur Hardware-Komponente findest du hier. + Weitere Informationen zur Hardware-Komponente findest du hier.
diff --git a/src/components/Tutorial/HintTutorialExists.js b/src/components/Tutorial/HintTutorialExists.js new file mode 100644 index 0000000..fa9b64f --- /dev/null +++ b/src/components/Tutorial/HintTutorialExists.js @@ -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 ( + +
+ Es gibt ab jetzt Tutorials zu verschiedenen Themen. Schau mal hier vorbei. + this.onChange(e)} + name="dialog" + color="primary" + /> + } + label={'Dialog nicht mehr anzeigen'} + /> +
+
+ ); + }; +} + +HintTutorialExists.propTypes = { + pageVisits: PropTypes.number.isRequired +}; + +const mapStateToProps = state => ({ + pageVisits: state.general.pageVisits +}); + +export default connect(mapStateToProps, null)(withStyles(styles, { withTheme: true })(HintTutorialExists)); diff --git a/src/components/Tutorial/StepperHorizontal.js b/src/components/Tutorial/StepperHorizontal.js index b4d87c0..6853550 100644 --- a/src/components/Tutorial/StepperHorizontal.js +++ b/src/components/Tutorial/StepperHorizontal.js @@ -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}
@@ -81,8 +82,8 @@ class StepperHorizontal extends Component {
@@ -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))); diff --git a/src/components/WorkspaceFunc.js b/src/components/WorkspaceFunc.js index 8c2d1af..253f9b4 100644 --- a/src/components/WorkspaceFunc.js +++ b/src/components/WorkspaceFunc.js @@ -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 = ''; diff --git a/src/data/Wenn-DannBedingungen.json b/src/data/Wenn-DannBedingungen.json deleted file mode 100644 index 8ade20c..0000000 --- a/src/data/Wenn-DannBedingungen.json +++ /dev/null @@ -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": "\n \n \n \n \n \n EQ\n \n \n Temperature\n \n \n \n \n \n \n \n \n 0\n \n" - }, - { - "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": "\n \n \n \n \n \n \n EQ\n \n \n isPressed\n 0\n \n \n \n \n TRUE\n \n \n \n \n \n \n 1\n HIGH\n \n \n \n \n EQ\n \n \n isPressed\n 0\n \n \n \n \n FALSE\n \n \n \n \n \n \n 1\n LOW\n \n \n \n \n \n" - } - ] -} \ No newline at end of file diff --git a/src/data/hardware.json b/src/data/hardware.json index 65c310a..3313f63 100644 --- a/src/data/hardware.json +++ b/src/data/hardware.json @@ -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" }, diff --git a/src/data/loops_01.json b/src/data/loops_01.json deleted file mode 100644 index 1f445e0..0000000 --- a/src/data/loops_01.json +++ /dev/null @@ -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": "\n \n \n \n 10\n \n \n \n" - }, - { - "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": "\n \n \n \n \n \n 5\n \n \n \n \n 1\n HIGH\n \n \n \n \n 1000\n \n \n \n \n 1\n LOW\n \n \n \n \n 1000\n \n \n \n \n \n \n \n \n \n \n \n \n \n" - }, - { - "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": "\n \n i\n \n \n \n \n i\n \n \n 100\n \n \n \n \n 1000\n \n \n \n \n 100\n \n \n \n \n 1\n HIGH\n \n \n \n \n i\n \n \n \n \n 1\n LOW\n \n \n \n \n i\n \n \n \n \n \n \n \n \n \n \n \n \n \n" - }, - { - "id": 5, - "type": "task", - "headline": "Schleifen mit Laufzeitvariable", - "text": "Verwende die Schleife mit Laufzeitvariable und beeinflusse die Blinkfrequenz mithilfe dem Wert der Variable.", - "xml": "\n \n i\n \n \n \n \n i\n \n \n 100\n \n \n \n \n 1000\n \n \n \n \n 100\n \n \n \n \n 1\n HIGH\n \n \n \n \n i\n \n \n \n \n 1\n LOW\n \n \n \n \n i\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n 1000\n \n" - } - ] -} \ No newline at end of file diff --git a/src/data/AnzeigeVonMesswertenAufDemDisplay.json b/src/data/tutorial/AnzeigeVonMesswertenAufDemDisplay.json similarity index 100% rename from src/data/AnzeigeVonMesswertenAufDemDisplay.json rename to src/data/tutorial/AnzeigeVonMesswertenAufDemDisplay.json diff --git a/src/data/ErsteSchritte.json b/src/data/tutorial/ErsteSchritte.json similarity index 100% rename from src/data/ErsteSchritte.json rename to src/data/tutorial/ErsteSchritte.json diff --git a/src/data/tutorial/Schleifen.json b/src/data/tutorial/Schleifen.json new file mode 100644 index 0000000..d081ad0 --- /dev/null +++ b/src/data/tutorial/Schleifen.json @@ -0,0 +1 @@ +{"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":"\n \n \n \n 10\n \n \n \n"},{"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":"\n \n \n \n \n \n 5\n \n \n \n \n 1\n HIGH\n \n \n \n \n 1000\n \n \n \n \n 1\n LOW\n \n \n \n \n 1000\n \n \n \n \n \n \n \n \n \n \n \n \n \n"},{"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":"\n \n i\n \n \n \n \n i\n \n \n 100\n \n \n \n \n 1000\n \n \n \n \n 100\n \n \n \n \n 1\n HIGH\n \n \n \n \n i\n \n \n \n \n 1\n LOW\n \n \n \n \n i\n \n \n \n \n \n \n \n \n \n \n \n \n \n"},{"id":5,"type":"task","headline":"Schleifen mit Laufzeitvariable","text":"Verwende die Schleife mit Laufzeitvariable und beeinflusse die Blinkfrequenz mithilfe dem Wert der Variable.","xml":"\n \n i\n \n \n \n \n i\n \n \n 100\n \n \n \n \n 1000\n \n \n \n \n 100\n \n \n \n \n 1\n HIGH\n \n \n \n \n i\n \n \n \n \n 1\n LOW\n \n \n \n \n i\n \n \n \n \n \n \n \n \n \n \n \n \n \n"}]} \ No newline at end of file diff --git a/src/data/tutorial/VerwendungVonVariablen.json b/src/data/tutorial/VerwendungVonVariablen.json new file mode 100644 index 0000000..3f883ba --- /dev/null +++ b/src/data/tutorial/VerwendungVonVariablen.json @@ -0,0 +1 @@ +{"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":"\n \n Temperatur\n \n \n \n \n \n \n \n Temperatur\n \n \n Temperature\n \n \n \n \n \n \n WHITE,BLACK\n 1\n 0\n 0\n \n \n Temperatur\n \n \n \n \n \n \n \n \n \n"},{"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":"\n \n Temperatur\n Luftfeuchte\n \n \n \n \n \n \n \n Temperatur\n \n \n Temperature\n \n \n \n \n Luftfeuchte\n \n \n Temperature\n \n \n \n \n \n \n WHITE,BLACK\n 1\n 0\n 0\n \n \n Luftfeuchte\n \n \n \n \n WHITE,BLACK\n 1\n 0\n 20\n \n \n Temperatur\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n"}]} \ No newline at end of file diff --git a/src/data/tutorial/Wenn-DannBedingungen.json b/src/data/tutorial/Wenn-DannBedingungen.json new file mode 100644 index 0000000..33dba31 --- /dev/null +++ b/src/data/tutorial/Wenn-DannBedingungen.json @@ -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":"\n \n \n \n \n \n EQ\n \n \n Temperature\n \n \n \n \n 0\n \n \n \n \n \n \n \n"},{"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":"\n \n \n \n \n \n \n EQ\n \n \n isPressed\n 0\n \n \n \n \n TRUE\n \n \n \n \n \n \n 1\n HIGH\n \n \n \n \n EQ\n \n \n isPressed\n 0\n \n \n \n \n FALSE\n \n \n \n \n \n \n 1\n LOW\n \n \n \n \n \n"}]} \ No newline at end of file diff --git a/src/data/tutorials.js b/src/data/tutorials.js index 67471a9..fb1fe39 100644 --- a/src/data/tutorials.js +++ b/src/data/tutorials.js @@ -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; \ No newline at end of file + +module.exports = tutorials; diff --git a/src/data/variablen_01.json b/src/data/variablen_01.json deleted file mode 100644 index 7f73f99..0000000 --- a/src/data/variablen_01.json +++ /dev/null @@ -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": "\n \n Temperatur\n \n \n \n \n \n \n \n Temperatur\n \n \n Temperature\n \n \n \n \n \n \n WHITE,BLACK\n 1\n 0\n 0\n \n \n \n \n \n \n \n \n Temperatur\n \n" - }, - { - "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": "\n \n Temperatur\n Luftfeuchte\n \n \n \n \n \n \n \n Temperatur\n \n \n Temperature\n \n \n \n \n Luftfeuchte\n \n \n Temperature\n \n \n \n \n \n \n WHITE,BLACK\n 1\n 0\n 0\n \n \n Luftfeuchte\n \n \n \n \n WHITE,BLACK\n 1\n 0\n 20\n \n \n Temperatur\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n" - } - ] -} \ No newline at end of file diff --git a/src/reducers/generalReducer.js b/src/reducers/generalReducer.js new file mode 100644 index 0000000..2d1c875 --- /dev/null +++ b/src/reducers/generalReducer.js @@ -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; + } +} diff --git a/src/reducers/index.js b/src/reducers/index.js index 948fd68..077c60c 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -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 }); diff --git a/src/reducers/tutorialReducer.js b/src/reducers/tutorialReducer.js index c0eb18b..c231f78 100644 --- a/src/reducers/tutorialReducer.js +++ b/src/reducers/tutorialReducer.js @@ -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 {