commit
ad1e5f1b82
93
NEWS.md
Normal file
93
NEWS.md
Normal file
@ -0,0 +1,93 @@
|
||||
# Blockly 2020
|
||||
|
||||
(aktuelles Preview unter: https://deploy-preview-37--blockly-react.netlify.app/)
|
||||
|
||||
In den letzten Wochen haben wir eine komplett neue Lern- und Programmierumgebung für die senseBox geschaffen. Die Basis bildet hierbei weiterhin Google Blockly und das Frontend wird über React realisiert. Fast alle Blöcke wurden bereits aus der alten Version in die neue Version migriert.
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
## Blockly Core
|
||||
Nachdem die bisherige Version, die unter [blockly.sensebox.de](https://blockly.sensebox.de) verfügbar ist, auf einen Google Blockly Core von 2016 aufbaut, wurde es Zeit ein großes Update durchzuführen. Durch den neuen Blockly Core lassen sich auch andere Renderer der Blöcke verwenden. In den Einstellungen kannst du zwischen den zwei Renderern Geras und Zelos auswählen. Geras ist der klassische Blockly Renderer während Zelos vor allem für Touchoberfläche optimiert worden ist.
|
||||
|
||||
### Typed Variablen
|
||||
|
||||
Neue Variablen werden nun direkt mit einem bestimmten Datentyp angelegt. Ein einfacher Check überprüft ob der zurückgegeben Typ eines Blockes mit dem der Variablen kompatibel ist.
|
||||
|
||||

|
||||
|
||||
|
||||
### Funktionen (funktioniert aktuell nicht!)
|
||||
|
||||
Funktionen mit Rückgabe Wert und Eingabeparametern können angelegt werden. Durch die Verwendung von Funktionen lassen sich auch komplexere Programme übersichtlicher darstellen und bearbeiten. Beim Anlegen einer Funktion kann über das Zahnrad weitere Eingabeparameter hinzuefügt werden.
|
||||
|
||||

|
||||
|
||||
|
||||
### GPS
|
||||
|
||||
Der Code für das GPS Modul wurde neu aufgebaut und ermöglicht es deutlich schneller einen GPS Fix zu bekommen. Zusätzlich lassen sich bald! die Koordinaten in zwei verschiedenen Formaten zurückgebenlassen. Zum einen als Kommazahl zum anderen als Zahl ohne nachkommastellen
|
||||
|
||||
### MQTT
|
||||
Zwei einfache Blöcke ermöglichen es nun die Daten über MQTT an einen Broker zu versenden. Zwei Broker sind bereits "vorprogrammiert" (Adafruit IO und DIOTY). Natürlich können auch eigene Broker verwendet werden. Falls ihr gute freie Broker kennt, die wir hinzufügen sollten meldet euch einfach bei uns.
|
||||
|
||||

|
||||
|
||||
|
||||
### TTN Mapper
|
||||
Bisher war es möglich einen "kleinen" TTN Mapper zu bauen, der die Daten als Cayenne Payload versendet hat. Es gibt nun einen Block der es direkt ermöglicht einen vollständigen TTN Mapper zu Programmieren, der die Daten auch auf [TTNMapper](https://ttnmapper.org/) veröffentlichen kann.
|
||||
|
||||

|
||||
|
||||
|
||||
## Fronted
|
||||
|
||||
In der Oberfläche gibt es einige Neuigkeiten. Ziel ist es Blockly für die senseBox zu einer vollständigen Lern- und Programmierumgebung weiterzuentwickeln.
|
||||
|
||||
Die Codeanzeige ist standardmäßig ausgeblendet kann aber einfach durch eine Klick auf das `</>` Icon hinzugefügt werden.
|
||||
|
||||
### Login mit openSenseMap/senseBox Account
|
||||
|
||||
Im Menü unter Login könnt ihr euch mit eurem openSenseMap Account anmelden. Sobald ihr angemeldet seid habt ihr die Möglichkeit Projekte online zu speichern.
|
||||
Sobald der Login mit dem openSenseMap Account erfolgreich war lassen sich die bereits registrierten senseBox unter Account einsehen.
|
||||
|
||||

|
||||
|
||||
|
||||
Im Block zum senden an die openSenseMap müssen dann auch keine IDs mehr ausgewählt werden sondern die registrierten senseBox können einfach aus dem Dropdown Menü ausgewählt werden.
|
||||
|
||||

|
||||
|
||||
### Speichern von Projekten
|
||||
|
||||
Nach dem Login über den openSenseMap Account lassen sich Projekte online speichern und wieder abrufen
|
||||
|
||||

|
||||
|
||||
|
||||
### Tutorials
|
||||
|
||||
Es gibt jetzt Tutorials! Eine reihe von verschiedenen Tutorials zeigt dir die ersten Schritte in der Programmierung mit Blockly. (Inhalte werden noch ausgebaut)
|
||||
|
||||

|
||||
|
||||
### Gallery
|
||||
|
||||
In der Gallery finden sich Beispiele mit verschiedenen Programmen. Die Beispiele können direkt in Blockly geöffnet werden, um Änderungen vorzunehmen oder das Programm direkt auf deine senseBox zu übertragen.
|
||||
|
||||

|
||||
|
||||
|
||||
### Teilen von Programmen
|
||||
|
||||
Über den Share Button kann ein Link zum Teilen der aktuellen Blöcke erstellt werden. Wann immer du dein Projekt mit anderen Teilen willst musst du nicht mehr eine XML Datei erstellen und verschicken sondern kannst einen Link erstellen, der direkt zu deinem Programm führt. Beachte, dass vor dem Teilen von Blöcken sämtliche sensiblen Daten, wie zum Beispiel Passwörter, Netzwerknamen, Lora oder openSenseMap Keys entfernt werden sollten. Die Links zum teilen von Programmen laufen nach 30 Tagen ab.
|
||||
|
||||

|
||||
|
||||
|
||||
## Fehler
|
||||
|
||||
Falls ihr Fehler findet legt bitte ein Issue in folgendem Repository an: https://github.com/sensebox/React-Ardublockly/issues
|
||||
|
205
package-lock.json
generated
205
package-lock.json
generated
@ -1143,6 +1143,24 @@
|
||||
"resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz",
|
||||
"integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow=="
|
||||
},
|
||||
"@emotion/is-prop-valid": {
|
||||
"version": "0.8.8",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz",
|
||||
"integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==",
|
||||
"requires": {
|
||||
"@emotion/memoize": "0.7.4"
|
||||
}
|
||||
},
|
||||
"@emotion/memoize": {
|
||||
"version": "0.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz",
|
||||
"integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw=="
|
||||
},
|
||||
"@emotion/unitless": {
|
||||
"version": "0.7.5",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz",
|
||||
"integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg=="
|
||||
},
|
||||
"@fortawesome/fontawesome-common-types": {
|
||||
"version": "0.2.30",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.30.tgz",
|
||||
@ -1479,6 +1497,11 @@
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz",
|
||||
"integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw=="
|
||||
},
|
||||
"@rooks/use-mutation-observer": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@rooks/use-mutation-observer/-/use-mutation-observer-3.4.0.tgz",
|
||||
"integrity": "sha512-q10+v3WbvSt5fj55VMikTPaUZ9Yl+IYDsymodWr2+cKx0PD97VBeWYjk3xHJPqJgejBHwnrwiNkJKGFY5iW+WQ=="
|
||||
},
|
||||
"@sheerun/mutationobserver-shim": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.3.tgz",
|
||||
@ -2786,6 +2809,22 @@
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.6.tgz",
|
||||
"integrity": "sha512-1aGDUfL1qOOIoqk9QKGIo2lANk+C7ko/fqH0uIyC71x3PEGz0uVP8ISgfEsFuG+FKmjHTvFK/nNM8dowpmUxLA=="
|
||||
},
|
||||
"babel-plugin-styled-components": {
|
||||
"version": "1.12.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.12.0.tgz",
|
||||
"integrity": "sha512-FEiD7l5ZABdJPpLssKXjBUJMYqzbcNzBowfXDCdJhOpbhWiewapUaY+LZGT8R4Jg2TwOjGjG4RKeyrO5p9sBkA==",
|
||||
"requires": {
|
||||
"@babel/helper-annotate-as-pure": "^7.0.0",
|
||||
"@babel/helper-module-imports": "^7.0.0",
|
||||
"babel-plugin-syntax-jsx": "^6.18.0",
|
||||
"lodash": "^4.17.11"
|
||||
}
|
||||
},
|
||||
"babel-plugin-syntax-jsx": {
|
||||
"version": "6.18.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
|
||||
"integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY="
|
||||
},
|
||||
"babel-plugin-syntax-object-rest-spread": {
|
||||
"version": "6.13.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
|
||||
@ -3553,6 +3592,11 @@
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
|
||||
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
|
||||
},
|
||||
"camelize": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz",
|
||||
"integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs="
|
||||
},
|
||||
"caniuse-api": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
|
||||
@ -3725,6 +3769,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"classnames": {
|
||||
"version": "2.2.6",
|
||||
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz",
|
||||
"integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q=="
|
||||
},
|
||||
"clean-css": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz",
|
||||
@ -4216,6 +4265,11 @@
|
||||
"postcss": "^7.0.5"
|
||||
}
|
||||
},
|
||||
"css-color-keywords": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
|
||||
"integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU="
|
||||
},
|
||||
"css-color-names": {
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz",
|
||||
@ -4306,6 +4360,23 @@
|
||||
"resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz",
|
||||
"integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w=="
|
||||
},
|
||||
"css-to-react-native": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-2.3.2.tgz",
|
||||
"integrity": "sha512-VOFaeZA053BqvvvqIA8c9n0+9vFppVBAHCp6JgFTtTMU3Mzi+XnelJ9XC9ul3BqFzZyQ5N+H0SnwsWT2Ebchxw==",
|
||||
"requires": {
|
||||
"camelize": "^1.0.0",
|
||||
"css-color-keywords": "^1.0.0",
|
||||
"postcss-value-parser": "^3.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"postcss-value-parser": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
|
||||
"integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"css-tree": {
|
||||
"version": "1.0.0-alpha.37",
|
||||
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz",
|
||||
@ -4698,6 +4769,11 @@
|
||||
"resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz",
|
||||
"integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw=="
|
||||
},
|
||||
"detect-node-es": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.0.0.tgz",
|
||||
"integrity": "sha512-S4AHriUkTX9FoFvL4G8hXDcx6t3gp2HpfCza3Q0v6S78gul2hKWifLQbeW+ZF89+hSm2ZIc/uF3J97ZgytgTRg=="
|
||||
},
|
||||
"detect-port-alt": {
|
||||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz",
|
||||
@ -6138,6 +6214,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"focus-lock": {
|
||||
"version": "0.6.8",
|
||||
"resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-0.6.8.tgz",
|
||||
"integrity": "sha512-vkHTluRCoq9FcsrldC0ulQHiyBYgVJB2CX53I8r0nTC6KnEij7Of0jpBspjt3/CuNb6fyoj3aOh9J2HgQUM0og=="
|
||||
},
|
||||
"focus-outline-manager": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/focus-outline-manager/-/focus-outline-manager-1.0.2.tgz",
|
||||
"integrity": "sha1-e/NliGU0H7awjQQqA3udKGixGbU="
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.12.1",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.12.1.tgz",
|
||||
@ -7387,6 +7473,11 @@
|
||||
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
||||
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
|
||||
},
|
||||
"is-what": {
|
||||
"version": "3.12.0",
|
||||
"resolved": "https://registry.npmjs.org/is-what/-/is-what-3.12.0.tgz",
|
||||
"integrity": "sha512-2ilQz5/f/o9V7WRWJQmpFYNmQFZ9iM+OXRonZKcYgTkCzjb949Vi4h282PD1UfmgHk666rcWonbRJ++KI41VGw=="
|
||||
},
|
||||
"is-windows": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
|
||||
@ -8413,11 +8504,21 @@
|
||||
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
|
||||
"integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY="
|
||||
},
|
||||
"lodash.debounce": {
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
|
||||
"integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168="
|
||||
},
|
||||
"lodash.memoize": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
|
||||
"integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4="
|
||||
},
|
||||
"lodash.pick": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz",
|
||||
"integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM="
|
||||
},
|
||||
"lodash.sortby": {
|
||||
"version": "4.7.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
|
||||
@ -8590,6 +8691,11 @@
|
||||
"p-is-promise": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"memoize-one": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.1.1.tgz",
|
||||
"integrity": "sha512-HKeeBpWvqiVJD57ZUAsJNm71eHTykffzcLZVYWiVfQeI1rJtuEaS7hQiEpWfVVk18donPwJEcFKIkCmPJNOhHA=="
|
||||
},
|
||||
"memory-fs": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz",
|
||||
@ -8623,6 +8729,14 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"merge-anything": {
|
||||
"version": "2.4.4",
|
||||
"resolved": "https://registry.npmjs.org/merge-anything/-/merge-anything-2.4.4.tgz",
|
||||
"integrity": "sha512-l5XlriUDJKQT12bH+rVhAHjwIuXWdAIecGwsYjv2LJo+dA1AeRTmeQS+3QBpO6lEthBMDi2IUMpLC1yyRvGlwQ==",
|
||||
"requires": {
|
||||
"is-what": "^3.3.1"
|
||||
}
|
||||
},
|
||||
"merge-deep": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/merge-deep/-/merge-deep-3.0.2.tgz",
|
||||
@ -10971,6 +11085,14 @@
|
||||
"whatwg-fetch": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"react-clientside-effect": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/react-clientside-effect/-/react-clientside-effect-1.2.2.tgz",
|
||||
"integrity": "sha512-nRmoyxeok5PBO6ytPvSjKp9xwXg9xagoTK1mMjwnQxqM9Hd7MNPl+LS1bOSOe+CV2+4fnEquc7H/S8QD3q697A==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"react-cookie-consent": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-cookie-consent/-/react-cookie-consent-5.2.0.tgz",
|
||||
@ -11196,6 +11318,19 @@
|
||||
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.7.tgz",
|
||||
"integrity": "sha512-TAv1KJFh3RhqxNvhzxj6LeT5NWklP6rDr2a0jaTfsZ5wSZWHOGeqQyejUp3xxLfPt2UpyJEcVQB/zyPcmonNFA=="
|
||||
},
|
||||
"react-focus-lock": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.2.1.tgz",
|
||||
"integrity": "sha512-47g0xYcCTZccdzKRGufepY8oZ3W1Qg+2hn6u9SHZ0zUB6uz/4K4xJe7yYFNZ1qT6m+2JDm82F6QgKeBTbjW4PQ==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.0.0",
|
||||
"focus-lock": "^0.6.6",
|
||||
"prop-types": "^15.6.2",
|
||||
"react-clientside-effect": "^1.2.2",
|
||||
"use-callback-ref": "^1.2.1",
|
||||
"use-sidecar": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
@ -11347,6 +11482,22 @@
|
||||
"prop-types": "^15.6.2"
|
||||
}
|
||||
},
|
||||
"reactour": {
|
||||
"version": "1.18.0",
|
||||
"resolved": "https://registry.npmjs.org/reactour/-/reactour-1.18.0.tgz",
|
||||
"integrity": "sha512-de0Pa5NkDU6I8IyGl+7+rWdDcx3AskmJYK/yIKU11D9EPIN79qzn852gjJgvH/jXZqeEfa+rmMWg72vA0UkmgA==",
|
||||
"requires": {
|
||||
"@rooks/use-mutation-observer": "3.4.0",
|
||||
"classnames": "2.2.6",
|
||||
"focus-outline-manager": "^1.0.2",
|
||||
"lodash.debounce": "4.0.8",
|
||||
"lodash.pick": "4.4.0",
|
||||
"prop-types": "15.7.2",
|
||||
"react-focus-lock": "2.2.1",
|
||||
"scroll-smooth": "1.1.0",
|
||||
"scrollparent": "2.0.1"
|
||||
}
|
||||
},
|
||||
"read-pkg": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
|
||||
@ -11959,6 +12110,16 @@
|
||||
"ajv-keywords": "^3.4.1"
|
||||
}
|
||||
},
|
||||
"scroll-smooth": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/scroll-smooth/-/scroll-smooth-1.1.0.tgz",
|
||||
"integrity": "sha512-68OUOXKN/ykM/Dbp4Lhza3O9QQUuW/c01WTsZzDOUyVgb1I5QjT/awOHCCbuYTSV1QnExUQ9w+KcxmVxlXIiAg=="
|
||||
},
|
||||
"scrollparent": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/scrollparent/-/scrollparent-2.0.1.tgz",
|
||||
"integrity": "sha1-cV1bnMV3YPsivczDvvtb/gaxoxc="
|
||||
},
|
||||
"select": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
|
||||
@ -12842,6 +13003,26 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"styled-components": {
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/styled-components/-/styled-components-4.4.1.tgz",
|
||||
"integrity": "sha512-RNqj14kYzw++6Sr38n7197xG33ipEOktGElty4I70IKzQF1jzaD1U4xQ+Ny/i03UUhHlC5NWEO+d8olRCDji6g==",
|
||||
"requires": {
|
||||
"@babel/helper-module-imports": "^7.0.0",
|
||||
"@babel/traverse": "^7.0.0",
|
||||
"@emotion/is-prop-valid": "^0.8.1",
|
||||
"@emotion/unitless": "^0.7.0",
|
||||
"babel-plugin-styled-components": ">= 1",
|
||||
"css-to-react-native": "^2.2.2",
|
||||
"memoize-one": "^5.0.0",
|
||||
"merge-anything": "^2.2.4",
|
||||
"prop-types": "^15.5.4",
|
||||
"react-is": "^16.6.0",
|
||||
"stylis": "^3.5.0",
|
||||
"stylis-rule-sheet": "^0.0.10",
|
||||
"supports-color": "^5.5.0"
|
||||
}
|
||||
},
|
||||
"stylehacks": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz",
|
||||
@ -12864,6 +13045,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"stylis": {
|
||||
"version": "3.5.4",
|
||||
"resolved": "https://registry.npmjs.org/stylis/-/stylis-3.5.4.tgz",
|
||||
"integrity": "sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q=="
|
||||
},
|
||||
"stylis-rule-sheet": {
|
||||
"version": "0.0.10",
|
||||
"resolved": "https://registry.npmjs.org/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz",
|
||||
"integrity": "sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw=="
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
@ -13536,6 +13727,20 @@
|
||||
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
|
||||
"integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
|
||||
},
|
||||
"use-callback-ref": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.2.4.tgz",
|
||||
"integrity": "sha512-rXpsyvOnqdScyied4Uglsp14qzag1JIemLeTWGKbwpotWht57hbP78aNT+Q4wdFKQfQibbUX4fb6Qb4y11aVOQ=="
|
||||
},
|
||||
"use-sidecar": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.0.3.tgz",
|
||||
"integrity": "sha512-ygJwGUBeQfWgDls7uTrlEDzJUUR67L8Rm14v/KfFtYCdHhtjHZx1Krb3DIQl3/Q5dJGfXLEQ02RY8BdNBv87SQ==",
|
||||
"requires": {
|
||||
"detect-node-es": "^1.0.0",
|
||||
"tslib": "^1.9.3"
|
||||
}
|
||||
},
|
||||
"util": {
|
||||
"version": "0.10.3",
|
||||
"resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
|
||||
|
@ -26,8 +26,10 @@
|
||||
"react-redux": "^7.2.0",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-scripts": "3.4.1",
|
||||
"reactour": "^1.18.0",
|
||||
"redux": "^4.0.5",
|
||||
"redux-thunk": "^2.3.0",
|
||||
"styled-components": "^4.4.1",
|
||||
"uuid": "^8.3.1"
|
||||
},
|
||||
"scripts": {
|
||||
|
@ -15,6 +15,14 @@
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.news img{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
max-height: 40vH;
|
||||
max-width: 100%;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.tutorial blockquote{
|
||||
background: #f9f9f9;
|
||||
border-left: 10px solid#4EAF47;
|
||||
|
@ -880,7 +880,7 @@ Blockly.Msg.messages_copylink_success = 'Link erfolgreich in Zwischenablage gesp
|
||||
Blockly.Msg.messages_rename_success_01 = 'Das Projekt wurde erfolgreich in '
|
||||
Blockly.Msg.messages_rename_success_02 = 'umbenannt.'
|
||||
Blockly.Msg.messages_newblockly_head = "Willkommen zur neuen Version Blockly für die senseBox"
|
||||
Blockly.Msg.messages_newblockly_text = "Die neue Blockly Version befindet sich zurzeit in der Testphase. Alle Neuigkeiten findet ihr hier:"
|
||||
Blockly.Msg.messages_newblockly_text = "Die neue Blockly Version befindet sich zurzeit in der Testphase. Alle Neuigkeiten findet ihr hier: "
|
||||
Blockly.Msg.messages_GET_TUTORIAL_FAIL = 'Zurück zur Tutorials-Übersicht'
|
||||
Blockly.Msg.messages_LOGIN_FAIL = 'Der Benutzername oder das Passwort ist nicht korrekt.'
|
||||
/**
|
||||
@ -1024,4 +1024,27 @@ Blockly.Msg.codeviewer_arduino = "Arduino Quellcode"
|
||||
Blockly.Msg.codeviewer_xml = "XML Blöcke"
|
||||
|
||||
|
||||
/**
|
||||
* Home Tour
|
||||
*/
|
||||
Blockly.Msg.hometour_wrapper = "Willkommen zu Blockly für die senseBox. In dieser Tour werde ich dir alle wichtigen Funktionen der Oberfläche zeigen"
|
||||
Blockly.Msg.hometour_workspaceFunc = "Hier findest du alle Buttons um dein Programm zu übertragen, zu speichern oder zu teilen"
|
||||
Blockly.Msg.hometour_blocklyWindow = "Dies ist deine Arbeitsfläche. Hier kannst du mithilfe der Blöcke deinen Programmcode erstellen"
|
||||
Blockly.Msg.hometour_blocklyToolboxDiv = "In der Toolbox befinden sich alle Blöcke. Verbinde diese in der Arbeitsfläche und erstelle dein Programmcode"
|
||||
Blockly.Msg.hometour_compileBlocks = "Wenn du fertig mit dem Programmieren bist und deinen Programmcode auf die senseBox übertragen möchtest klicke hier um deinen Programmcode zu kompilieren."
|
||||
Blockly.Msg.hometour_menuButton = "Im Menü findest du Tutorials und eine Gallery mit verschiedenen Beispiel Programmen. Logge dich über deinen openSenseMap Account ein und du erhälst noch mehr Funktionen"
|
||||
Blockly.Msg.hometour_showCode = "Über diesen Button kannst du dir den generierten Programmcode anzeigen lassen"
|
||||
Blockly.Msg.hometour_shareBlocks = "Erstelle über diesen Button einen Kurzlink und teile deine Blöcke mit anderen Nutzer:innen"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Assessment Tour
|
||||
*/
|
||||
|
||||
Blockly.Msg.assessmenttour_solutionCheck = "Wenn deine Lösung fertig ist klicke hier um diese zu überprüfen"
|
||||
Blockly.Msg.assessmenttour_assessmentDiv = "Los gehts! Löse die folgende Aufgabe, um das Tutorial abzuschließen. "
|
||||
Blockly.Msg.assessmenttour_injectionDiv = "Erstelle hier deine Lösung. Du kannst alle Blöcke aus der Toolbox verwenden."
|
||||
|
||||
|
||||
export const De = Blockly.Msg;
|
||||
|
@ -847,7 +847,7 @@ Blockly.Msg.messages_copylink_success = 'Link successfully saved to clipboard.'
|
||||
Blockly.Msg.messages_rename_success_01 = 'The project was successfully saved to '
|
||||
Blockly.Msg.messages_rename_success_02 = 'renamed.'
|
||||
Blockly.Msg.messages_newblockly_head = 'Welcome to the new version Blockly for the senseBox'
|
||||
Blockly.Msg.messages_newblockly_text = "The new Blockly version is currently in testing. You can find all the news here:"
|
||||
Blockly.Msg.messages_newblockly_text = "The new Blockly version is currently in testing. You can find all the news here: "
|
||||
Blockly.Msg.messages_GET_TUTORIAL_FAIL = 'Back to tutorials overview'
|
||||
Blockly.Msg.messages_LOGIN_FAIL = 'The username or password is incorrect.'
|
||||
Blockly.Msg.messages_login_error = "Enter both a username and a password."
|
||||
@ -987,4 +987,27 @@ Blockly.Msg.navbar_settings = "Settings"
|
||||
Blockly.Msg.codeviewer_arduino = "Arduino Source Code"
|
||||
Blockly.Msg.codeviewer_xml = "XML Blocks"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Home Tour
|
||||
*/
|
||||
Blockly.Msg.hometour_wrapper = "Welcome to the new Learn- and Programmingapp for the senseBox. In this tour I will show you all the important features of the interface"
|
||||
Blockly.Msg.hometour_workspaceFunc = "Here you will find all the buttons to compile, save or share your program"
|
||||
Blockly.Msg.hometour_blocklyWindow = "This is your workspace. Here you can use the blocks to create your program code"
|
||||
Blockly.Msg.hometour_blocklyToolboxDiv = "The toolbox contains all the blocks. Connect them in the workspace and create your program code."
|
||||
Blockly.Msg.hometour_compileBlocks = "When you are done programming and want to transfer your program code to the senseBox click here to compile your program code."
|
||||
Blockly.Msg.hometour_menuButton = "In the menu you will find tutorials and a gallery with different example programs. Log in with your openSenseMap account and you will get even more features."
|
||||
Blockly.Msg.hometour_showCode = "With this button you can show the generated program code"
|
||||
Blockly.Msg.hometour_shareBlocks = "Use this button to create a short link and share your blocks with other users"
|
||||
|
||||
|
||||
/**
|
||||
* Assessment Tour
|
||||
*/
|
||||
|
||||
Blockly.Msg.assessmenttour_solutionCheck = "When your solution is ready click here to check it"
|
||||
Blockly.Msg.assessmenttour_assessmentDiv = "Let's go! Solve the following task to complete the tutorial. "
|
||||
Blockly.Msg.assessmenttour_injectionDiv = "Create your solution here. You can use any blocks from the toolbox."
|
||||
|
||||
export const En = Blockly.Msg;
|
||||
|
@ -14,6 +14,8 @@ class Footer extends Component {
|
||||
<Typography style={{ margin: '0px 10px 0px 10px', display: 'initial', fontSize: '1rem' }}>|</Typography>
|
||||
<Link to={"/privacy"} style={{ textDecoration: 'none', color: 'inherit' }}>Privacy</Link>
|
||||
<Typography style={{ margin: '0px 10px 0px 10px', display: 'initial', fontSize: '1rem' }}>|</Typography>
|
||||
<Link to={"/news"} style={{ textDecoration: 'none', color: 'inherit' }}>News</Link>
|
||||
<Typography style={{ margin: '0px 10px 0px 10px', display: 'initial', fontSize: '1rem' }}>|</Typography>
|
||||
<a href="https://sensebox.de" style={{ textDecoration: 'none', color: 'inherit' }}>sensebox.de</a>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -56,10 +56,10 @@ class Home extends Component {
|
||||
|
||||
componentDidMount() {
|
||||
this.setState({ stats: window.localStorage.getItem('stats') });
|
||||
if(!this.props.project){
|
||||
if (!this.props.project) {
|
||||
this.props.workspaceName(createNameId());
|
||||
}
|
||||
if(this.props.message && this.props.message.id === 'GET_SHARE_FAIL'){
|
||||
if (this.props.message && this.props.message.id === 'GET_SHARE_FAIL') {
|
||||
this.setState({ snackbar: true, key: Date.now(), message: `Das angefragte geteilte Projekt konnte nicht gefunden werden.`, type: 'error' });
|
||||
}
|
||||
}
|
||||
@ -94,14 +94,14 @@ class Home extends Component {
|
||||
<div style={{ float: 'left', height: '40px', position: 'relative' }}><WorkspaceStats /></div>
|
||||
: null
|
||||
}
|
||||
<div style={{ float: 'right', height: '40px', marginBottom: '20px' }}>
|
||||
<WorkspaceFunc project={this.props.project} projectType={this.props.projectType}/>
|
||||
<div className='workspaceFunc' style={{ float: 'right', height: '40px', marginBottom: '20px' }}>
|
||||
<WorkspaceFunc project={this.props.project} projectType={this.props.projectType} />
|
||||
</div>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={12} md={this.state.codeOn ? 8 : 12} style={{ position: 'relative' }}>
|
||||
<Tooltip title={this.state.codeOn ? 'Code ausblenden' : 'Code anzeigen'} >
|
||||
<IconButton
|
||||
className={this.state.codeOn ? this.props.classes.codeOn : this.props.classes.codeOff}
|
||||
className={`showCode ${this.state.codeOn ? this.props.classes.codeOn : this.props.classes.codeOff}`}
|
||||
style={{ width: '40px', height: '40px', position: 'absolute', top: -12, right: 8, zIndex: 21 }}
|
||||
onClick={() => this.onChange()}
|
||||
>
|
||||
@ -109,16 +109,18 @@ class Home extends Component {
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<TrashcanButtons />
|
||||
{this.props.project ?
|
||||
< BlocklyWindow blocklyCSS={{ height: '80vH' }} initialXml={this.props.project.xml} />
|
||||
: < BlocklyWindow blocklyCSS={{ height: '80vH' }} />
|
||||
}
|
||||
<div className='blocklyWindow'>
|
||||
{this.props.project ?
|
||||
< BlocklyWindow blocklyCSS={{ height: '80vH' }} initialXml={this.props.project.xml} />
|
||||
: < BlocklyWindow blocklyCSS={{ height: '80vH' }} />
|
||||
}
|
||||
</div>
|
||||
</Grid>
|
||||
{this.state.codeOn ?
|
||||
<Grid item xs={12} md={4}>
|
||||
<CodeViewer />
|
||||
</Grid>
|
||||
: null}
|
||||
: null}
|
||||
</Grid>
|
||||
<HintTutorialExists />
|
||||
<Snackbar
|
||||
|
@ -1,13 +1,14 @@
|
||||
import React, { Component } from 'react';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
|
||||
import Container from '@material-ui/core/Container';
|
||||
class Impressum extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div style={{ margin: '0px 24px 0px 24px' }}>
|
||||
<h1>Impressum</h1>
|
||||
<Container fixed>
|
||||
<div style={{ margin: '0px 24px 0px 24px' }}>
|
||||
<h1>Impressum</h1>
|
||||
|
||||
<h2>Angaben gemäß § 5 TMG:</h2>
|
||||
<h2>Angaben gemäß § 5 TMG:</h2>
|
||||
Institut für Geoinformatik<br />
|
||||
Heisenbergstraße 2<br />
|
||||
Geo 1<br />
|
||||
@ -16,7 +17,7 @@ class Impressum extends Component {
|
||||
<h2>Kontakt:</h2>
|
||||
E-Mail: <a href="mailto:info@mybadges.org!">info@mybadges.org</a>
|
||||
|
||||
<h2>Verantwortlich für den Inhalt nach § 55 Abs. 2 RStV:</h2>
|
||||
<h2>Verantwortlich für den Inhalt nach § 55 Abs. 2 RStV:</h2>
|
||||
Geschäftsführende Direktorin Prof. Dr. Angela Schwering<br />
|
||||
Heisenbergstraße 2<br />
|
||||
Geo 1<br />
|
||||
@ -25,21 +26,22 @@ class Impressum extends Component {
|
||||
<h2>Streitschlichtung</h2>
|
||||
Die Europäische Kommission stellt eine Plattform zur Online-Streitbeilegung (OS) bereit: <a href="https://ec.europa.eu/consumers/odr" target="_blank" rel="noopener noreferrer">https://ec.europa.eu/consumers/odr</a>.<br />
|
||||
Unsere E-Mail-Adresse finden Sie oben im Impressum.<br />
|
||||
<p>Wir sind nicht bereit oder verpflichtet, an Streitbeilegungsverfahren vor einer Verbraucherschlichtungsstelle teilzunehmen.</p>
|
||||
<p>Wir sind nicht bereit oder verpflichtet, an Streitbeilegungsverfahren vor einer Verbraucherschlichtungsstelle teilzunehmen.</p>
|
||||
|
||||
<h3>Haftung für Inhalte</h3>
|
||||
<h3>Haftung für Inhalte</h3>
|
||||
Als Diensteanbieter sind wir gemäß § 7 Abs.1 TMG für eigene Inhalte auf diesen Seiten nach den allgemeinen Gesetzen verantwortlich. Nach §§ 8 bis 10 TMG sind wir als Diensteanbieter jedoch nicht verpflichtet, übermittelte oder gespeicherte fremde Informationen zu überwachen oder nach Umständen zu forschen, die auf eine rechtswidrige Tätigkeit hinweisen.
|
||||
<p>Verpflichtungen zur Entfernung oder Sperrung der Nutzung von Informationen nach den allgemeinen Gesetzen bleiben hiervon unberührt. Eine diesbezügliche Haftung ist jedoch erst ab dem Zeitpunkt der Kenntnis einer konkreten Rechtsverletzung möglich. Bei Bekanntwerden von entsprechenden Rechtsverletzungen werden wir diese Inhalte umgehend entfernen.</p>
|
||||
|
||||
<h3>Haftung für Links</h3>
|
||||
<h3>Haftung für Links</h3>
|
||||
Unser Angebot enthält Links zu externen Websites Dritter, auf deren Inhalte wir keinen Einfluss haben. Deshalb können wir für diese fremden Inhalte auch keine Gewähr übernehmen. Für die Inhalte der verlinkten Seiten ist stets der jeweilige Anbieter oder Betreiber der Seiten verantwortlich. Die verlinkten Seiten wurden zum Zeitpunkt der Verlinkung auf mögliche Rechtsverstöße überprüft. Rechtswidrige Inhalte waren zum Zeitpunkt der Verlinkung nicht erkennbar.
|
||||
<p>Eine permanente inhaltliche Kontrolle der verlinkten Seiten ist jedoch ohne konkrete Anhaltspunkte einer Rechtsverletzung nicht zumutbar. Bei Bekanntwerden von Rechtsverletzungen werden wir derartige Links umgehend entfernen.</p>
|
||||
|
||||
<h3>Urheberrecht</h3>
|
||||
<h3>Urheberrecht</h3>
|
||||
Die durch die Seitenbetreiber erstellten Inhalte und Werke auf diesen Seiten unterliegen dem deutschen Urheberrecht. Die Vervielfältigung, Bearbeitung, Verbreitung und jede Art der Verwertung außerhalb der Grenzen des Urheberrechtes bedürfen der schriftlichen Zustimmung des jeweiligen Autors bzw. Erstellers. Downloads und Kopien dieser Seite sind nur für den privaten, nicht kommerziellen Gebrauch gestattet.
|
||||
<p>Soweit die Inhalte auf dieser Seite nicht vom Betreiber erstellt wurden, werden die Urheberrechte Dritter beachtet. Insbesondere werden Inhalte Dritter als solche gekennzeichnet. Sollten Sie trotzdem auf eine Urheberrechtsverletzung aufmerksam werden, bitten wir um einen entsprechenden Hinweis. Bei Bekanntwerden von Rechtsverletzungen werden wir derartige Inhalte umgehend entfernen.</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
@ -20,10 +20,12 @@ import ListItem from '@material-ui/core/ListItem';
|
||||
import ListItemIcon from '@material-ui/core/ListItemIcon';
|
||||
import ListItemText from '@material-ui/core/ListItemText';
|
||||
import LinearProgress from '@material-ui/core/LinearProgress';
|
||||
|
||||
import { faBars, faChevronLeft, faLayerGroup, faSignInAlt, faSignOutAlt, faCertificate, faUserCircle, faCog, faChalkboardTeacher, faTools, faLightbulb } from "@fortawesome/free-solid-svg-icons";
|
||||
import Tour from 'reactour'
|
||||
import { home, assessment } from './Tour';
|
||||
import { faBars, faChevronLeft, faLayerGroup, faSignInAlt, faSignOutAlt, faCertificate, faUserCircle, faQuestionCircle, faCog, faChalkboardTeacher, faTools, faLightbulb } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import * as Blockly from 'blockly'
|
||||
import Tooltip from '@material-ui/core/Tooltip';
|
||||
|
||||
|
||||
const styles = (theme) => ({
|
||||
@ -34,6 +36,10 @@ const styles = (theme) => ({
|
||||
},
|
||||
appBarColor: {
|
||||
backgroundColor: theme.palette.primary.main
|
||||
},
|
||||
tourButton: {
|
||||
marginleft: 'auto',
|
||||
marginright: '30px',
|
||||
}
|
||||
});
|
||||
|
||||
@ -43,7 +49,8 @@ class Navbar extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
open: false
|
||||
open: false,
|
||||
isTourOpen: false
|
||||
};
|
||||
}
|
||||
|
||||
@ -51,7 +58,21 @@ class Navbar extends Component {
|
||||
this.setState({ open: !this.state.open });
|
||||
}
|
||||
|
||||
openTour = () => {
|
||||
this.setState({ isTourOpen: true });
|
||||
|
||||
}
|
||||
|
||||
closeTour = () => {
|
||||
this.setState({ isTourOpen: false });
|
||||
}
|
||||
|
||||
render() {
|
||||
var isHome = /^\/(\/.*$|$)/g.test(this.props.location.pathname);
|
||||
var isTutorial = /^\/tutorial(\/.*$|$)/g.test(this.props.location.pathname);
|
||||
var isAssessment = /^\/tutorial\/.{1,}$/g.test(this.props.location.pathname) &&
|
||||
!this.props.tutorialIsLoading && this.props.tutorial &&
|
||||
this.props.tutorial.steps[this.props.activeStep].type === 'task';
|
||||
return (
|
||||
<div>
|
||||
<AppBar
|
||||
@ -64,6 +85,7 @@ class Navbar extends Component {
|
||||
color="inherit"
|
||||
onClick={this.toggleDrawer}
|
||||
style={{ margin: '0 10px' }}
|
||||
className="MenuButton"
|
||||
>
|
||||
<FontAwesomeIcon icon={faBars} />
|
||||
</IconButton>
|
||||
@ -75,12 +97,41 @@ class Navbar extends Component {
|
||||
<Link to={"/"} style={{ marginLeft: '10px' }}>
|
||||
<img src={senseboxLogo} alt="senseBox-Logo" width="30" />
|
||||
</Link>
|
||||
{/^\/tutorial(\/.*$|$)/g.test(this.props.location.pathname) ?
|
||||
{isTutorial ?
|
||||
<Link to={"/tutorial"} style={{ textDecoration: 'none', color: 'inherit', marginLeft: '10px' }}>
|
||||
<Typography variant="h6" noWrap>
|
||||
Tutorial
|
||||
</Typography>
|
||||
</Link> : null}
|
||||
{isHome ?
|
||||
<Tooltip title='Hilfe starten' arrow>
|
||||
<IconButton
|
||||
color="inherit"
|
||||
className={`openTour ${this.props.classes.button}`}
|
||||
onClick={() => { this.openTour(); }}
|
||||
style={{ margin: '0 30px 0 auto' }}
|
||||
>
|
||||
<FontAwesomeIcon icon={faQuestionCircle} />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
: null}
|
||||
{isAssessment ?
|
||||
<Tooltip title='Hilfe starten' arrow>
|
||||
<IconButton
|
||||
color="inherit"
|
||||
className={`openTour ${this.props.classes.button}`}
|
||||
onClick={() => { this.openTour(); }}
|
||||
style={{ margin: '0 30px 0 auto' }}
|
||||
>
|
||||
<FontAwesomeIcon icon={faQuestionCircle} />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
: null}
|
||||
<Tour
|
||||
steps={isHome ? home() : assessment()}
|
||||
isOpen={this.state.isTourOpen}
|
||||
onRequestClose={() => { this.closeTour(); }}
|
||||
/>
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
<Drawer
|
||||
@ -152,14 +203,18 @@ Navbar.propTypes = {
|
||||
tutorialIsLoading: PropTypes.bool.isRequired,
|
||||
projectIsLoading: PropTypes.bool.isRequired,
|
||||
isAuthenticated: PropTypes.bool.isRequired,
|
||||
user: PropTypes.object
|
||||
user: PropTypes.object,
|
||||
tutorial: PropTypes.object.isRequired,
|
||||
activeStep: PropTypes.number.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
tutorialIsLoading: state.tutorial.progress,
|
||||
projectIsLoading: state.project.progress,
|
||||
isAuthenticated: state.auth.isAuthenticated,
|
||||
user: state.auth.user
|
||||
user: state.auth.user,
|
||||
tutorial: state.tutorial.tutorials[0],
|
||||
activeStep: state.tutorial.activeStep,
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, { logout })(withStyles(styles, { withTheme: true })(withRouter(Navbar)));
|
||||
|
154
src/components/News.js
Normal file
154
src/components/News.js
Normal file
@ -0,0 +1,154 @@
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import Breadcrumbs from './Breadcrumbs';
|
||||
|
||||
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'
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
import Container from '@material-ui/core/Container';
|
||||
|
||||
const news = `
|
||||
|
||||
# *17.12.2020* - Erstes Beta Release der neuen Lern- und Programmierumgebung für die senseBox
|
||||
|
||||
|
||||
In den letzten Wochen haben wir eine komplett neue Lern- und Programmierumgebung für die senseBox geschaffen. Die Basis bildet hierbei weiterhin Google Blockly und das Frontend wird über React realisiert. Fast alle Blöcke wurden bereits aus der alten Version in die neue Version migriert.
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
## Blockly Core
|
||||
Nachdem die bisherige Version, die unter [blockly.sensebox.de](https://blockly.sensebox.de) weiterhin verfügbar ist, auf einen Google Blockly Core von 2016 aufbaut, wurde es Zeit ein großes Update durchzuführen. Durch den neuen Blockly Core lassen sich auch andere Renderer der Blöcke verwenden. In den Einstellungen kannst du zwischen den zwei Renderern Geras und Zelos auswählen. Geras ist der klassische Blockly Renderer während Zelos vor allem für Touchoberfläche optimiert worden ist.
|
||||
|
||||
### Typed Variablen
|
||||
|
||||
Neue Variablen werden nun direkt mit einem bestimmten Datentyp angelegt. Ein einfacher Check überprüft ob der zurückgegeben Typ eines Blockes mit dem der Variablen kompatibel ist.
|
||||
|
||||

|
||||
|
||||
|
||||
### Funktionen (funktioniert aktuell nicht!)
|
||||
|
||||
Funktionen mit Rückgabe Wert und Eingabeparametern können angelegt werden. Durch die Verwendung von Funktionen lassen sich auch komplexere Programme übersichtlicher darstellen und bearbeiten. Beim Anlegen einer Funktion kann über das Zahnrad weitere Eingabeparameter hinzuefügt werden.
|
||||
|
||||

|
||||
|
||||
|
||||
### GPS
|
||||
|
||||
Der Code für das GPS Modul wurde neu aufgebaut und ermöglicht es deutlich schneller einen GPS Fix zu bekommen. Zusätzlich lassen sich bald! die Koordinaten in zwei verschiedenen Formaten zurückgebenlassen. Zum einen als Kommazahl zum anderen als Zahl ohne nachkommastellen
|
||||
|
||||
### MQTT
|
||||
Zwei einfache Blöcke ermöglichen es nun die Daten über MQTT an einen Broker zu versenden. Zwei Broker sind bereits "vorprogrammiert" (Adafruit IO und DIOTY). Natürlich können auch eigene Broker verwendet werden. Falls ihr gute freie Broker kennt, die wir hinzufügen sollten meldet euch einfach bei uns.
|
||||
|
||||

|
||||
|
||||
|
||||
### TTN Mapper
|
||||
Bisher war es möglich einen "kleinen" TTN Mapper zu bauen, der die Daten als Cayenne Payload versendet hat. Es gibt nun einen Block der es direkt ermöglicht einen vollständigen TTN Mapper zu Programmieren, der die Daten auch auf [TTNMapper](https://ttnmapper.org/) veröffentlichen kann.
|
||||
|
||||

|
||||
|
||||
|
||||
## Fronted
|
||||
|
||||
In der Oberfläche gibt es einige Neuigkeiten. Ziel ist es Blockly für die senseBox zu einer vollständigen Lern- und Programmierumgebung weiterzuentwickeln.
|
||||
|
||||
Die Codeanzeige ist standardmäßig ausgeblendet kann aber einfach durch eine Klick auf das \`</>\` Icon hinzugefügt werden.
|
||||
|
||||
### Login mit openSenseMap/senseBox Account
|
||||
|
||||
Im Menü unter Login könnt ihr euch mit eurem openSenseMap Account anmelden. Sobald ihr angemeldet seid habt ihr die Möglichkeit Projekte online zu speichern.
|
||||
Sobald der Login mit dem openSenseMap Account erfolgreich war lassen sich die bereits registrierten senseBox unter Account einsehen.
|
||||
|
||||

|
||||
|
||||
|
||||
Im Block zum senden an die openSenseMap müssen dann auch keine IDs mehr ausgewählt werden sondern die registrierten senseBox können einfach aus dem Dropdown Menü ausgewählt werden.
|
||||
|
||||

|
||||
|
||||
### Speichern von Projekten
|
||||
|
||||
Nach dem Login über den openSenseMap Account lassen sich Projekte online speichern und wieder abrufen
|
||||
|
||||

|
||||
|
||||
|
||||
### Tutorials
|
||||
|
||||
Es gibt jetzt Tutorials! Eine reihe von verschiedenen Tutorials zeigt dir die ersten Schritte in der Programmierung mit Blockly. (Inhalte werden noch ausgebaut)
|
||||
|
||||

|
||||
|
||||
### Gallery
|
||||
|
||||
In der Gallery finden sich Beispiele mit verschiedenen Programmen. Die Beispiele können direkt in Blockly geöffnet werden, um Änderungen vorzunehmen oder das Programm direkt auf deine senseBox zu übertragen.
|
||||
|
||||

|
||||
|
||||
|
||||
### Teilen von Programmen
|
||||
|
||||
Über den Share Button kann ein Link zum Teilen der aktuellen Blöcke erstellt werden. Wann immer du dein Projekt mit anderen Teilen willst musst du nicht mehr eine XML Datei erstellen und verschicken sondern kannst einen Link erstellen, der direkt zu deinem Programm führt. Beachte, dass vor dem Teilen von Blöcken sämtliche sensiblen Daten, wie zum Beispiel Passwörter, Netzwerknamen, Lora oder openSenseMap Keys entfernt werden sollten. Die Links zum teilen von Programmen laufen nach 30 Tagen ab.
|
||||
|
||||

|
||||
|
||||
|
||||
## Fehler
|
||||
|
||||
Falls ihr Fehler findet legt bitte ein Issue in folgendem Repository an: [React-Ardublockly](https://github.com/sensebox/React-Ardublockly/issues)
|
||||
|
||||
|
||||
`
|
||||
|
||||
|
||||
|
||||
|
||||
class News 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>
|
||||
<Breadcrumbs content={[{ link: this.props.location.pathname, title: 'News' }]} />
|
||||
<Container fixed>
|
||||
<Typography variant='body1'><ReactMarkdown className="news" children={news}>
|
||||
</ReactMarkdown></Typography>
|
||||
</Container>
|
||||
{
|
||||
this.props.button ?
|
||||
<Button
|
||||
style={{ marginTop: '20px' }}
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={() => { this.props.history.push(this.props.button.link) }}
|
||||
>
|
||||
{this.props.button.title}
|
||||
</Button>
|
||||
:
|
||||
<Button
|
||||
style={{ marginTop: '20px' }}
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={() => { this.props.history.push('/') }}
|
||||
>
|
||||
{Blockly.Msg.button_back}
|
||||
</Button>
|
||||
}
|
||||
</div >
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default withRouter(News);
|
@ -1,18 +1,19 @@
|
||||
import React, { Component } from 'react';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
|
||||
import Container from '@material-ui/core/Container';
|
||||
class Privay extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div style={{ margin: '0px 24px 0px 24px' }}>
|
||||
<h1>Datenschutzerklärung</h1>
|
||||
<Container fixed>
|
||||
<div style={{ margin: '0px 24px 0px 24px' }}>
|
||||
<h1>Datenschutzerklärung</h1>
|
||||
|
||||
<h2>1. Datenschutz auf einen Blick</h2>
|
||||
<h3>Allgemeine Hinweise</h3>
|
||||
<h2>1. Datenschutz auf einen Blick</h2>
|
||||
<h3>Allgemeine Hinweise</h3>
|
||||
Die folgenden Hinweise geben einen einfachen Überblick darüber, was mit Ihren personenbezogenen Daten passiert, wenn Sie unsere Website besuchen. Personenbezogene Daten sind alle Daten, mit denen Sie persönlich identifiziert werden können. Ausführliche Informationen zum Thema Datenschutz entnehmen Sie unserer unter diesem Text aufgeführten Datenschutzerklärung.
|
||||
<h3>Datenerfassung auf unserer Website</h3>
|
||||
|
||||
<h4>Wer ist verantwortlich für die Datenerfassung auf dieser Website?</h4>
|
||||
<h4>Wer ist verantwortlich für die Datenerfassung auf dieser Website?</h4>
|
||||
|
||||
Die Datenverarbeitung auf dieser Website erfolgt durch den Websitebetreiber. Dessen Kontaktdaten können Sie dem Impressum dieser Website entnehmen.
|
||||
|
||||
@ -38,7 +39,7 @@ Sie können dieser Analyse widersprechen. Über die Widerspruchsmöglichkeiten w
|
||||
|
||||
|
||||
<h2>2. Allgemeine Hinweise und Pflichtinformationen</h2>
|
||||
<h3>Datenschutz</h3>
|
||||
<h3>Datenschutz</h3>
|
||||
Die Betreiber dieser Seiten nehmen den Schutz Ihrer persönlichen Daten sehr ernst.Wir behandeln Ihre personenbezogenen Daten vertraulich und entsprechend der gesetzlichen Datenschutzvorschriften sowie dieser Datenschutzerklärung.
|
||||
|
||||
Wenn Sie diese Website benutzen, werden verschiedene personenbezogene Daten erhoben.Personenbezogene Daten sind Daten, mit denen Sie persönlich identifiziert werden können.Die vorliegende Datenschutzerklärung erläutert, welche Daten wir erheben und wofür wir sie nutzen.Sie erläutert auch, wie und zu welchem Zweck das geschieht.
|
||||
@ -81,14 +82,14 @@ Gesetzlich vorgeschriebener Datenschutzbeauftragter
|
||||
Wir haben für unser Unternehmen einen Datenschutzbeauftragten bestellt.
|
||||
|
||||
<p>Institut für Geoinformatik</p>
|
||||
<p>Heisenbergstraße 2</p>
|
||||
<p>48149 Münster</p>
|
||||
<p>Heisenbergstraße 2</p>
|
||||
<p>48149 Münster</p>
|
||||
|
||||
<p>Telefon: +49(251) 83 - 33 083</p>
|
||||
<p>E - Mail: info@sensebox.de</p>
|
||||
<p>Telefon: +49(251) 83 - 33 083</p>
|
||||
<p>E - Mail: info@sensebox.de</p>
|
||||
|
||||
<h2>4. Datenerfassung auf unserer Website</h2>
|
||||
<h3>Cookies</h3>
|
||||
<h2>4. Datenerfassung auf unserer Website</h2>
|
||||
<h3>Cookies</h3>
|
||||
Die Internetseiten verwenden teilweise so genannte Cookies.Cookies richten auf Ihrem Rechner keinen Schaden an und enthalten keine Viren.Cookies dienen dazu, unser Angebot nutzerfreundlicher, effektiver und sicherer zu machen.Cookies sind kleine Textdateien, die auf Ihrem Rechner abgelegt werden und die Ihr Browser speichert.
|
||||
|
||||
Die meisten der von uns verwendeten Cookies sind so genannte “Session - Cookies”.Sie werden nach Ende Ihres Besuchs automatisch gelöscht.Andere Cookies bleiben auf Ihrem Endgerät gespeichert bis Sie diese löschen.Diese Cookies ermöglichen es uns, Ihren Browser beim nächsten Besuch wiederzuerkennen.
|
||||
@ -101,14 +102,14 @@ Sie können Ihren Browser so einstellen, dass Sie über das Setzen von Cookies i
|
||||
Der Provider der Seiten erhebt und speichert automatisch Informationen in so genannten Server - Log - Dateien, die Ihr Browser automatisch an uns übermittelt.Dies sind:
|
||||
<ul>
|
||||
|
||||
<li>Browsertyp und Browserversion</li>
|
||||
<li>verwendetes Betriebssystem</li>
|
||||
<li>Referrer URL</li>
|
||||
<li>Hostname des zugreifenden Rechners</li>
|
||||
<li>Uhrzeit der Serveranfrage</li>
|
||||
<li>
|
||||
IP - Adresse</li>
|
||||
</ul>
|
||||
<li>Browsertyp und Browserversion</li>
|
||||
<li>verwendetes Betriebssystem</li>
|
||||
<li>Referrer URL</li>
|
||||
<li>Hostname des zugreifenden Rechners</li>
|
||||
<li>Uhrzeit der Serveranfrage</li>
|
||||
<li>
|
||||
IP - Adresse</li>
|
||||
</ul>
|
||||
|
||||
Eine Zusammenführung dieser Daten mit anderen Datenquellen wird nicht vorgenommen.
|
||||
|
||||
@ -164,8 +165,8 @@ Wenn Sie mit der Speicherung und Nutzung Ihrer Daten nicht einverstanden sind, k
|
||||
|
||||
|
||||
|
||||
<h2>Plugins und Tools</h2>
|
||||
<h3>YouTube</h3>
|
||||
<h2>Plugins und Tools</h2>
|
||||
<h3>YouTube</h3>
|
||||
Unsere Website nutzt Plugins der von Google betriebenen Seite YouTube.Betreiber der Seiten ist die YouTube, LLC, 901 Cherry Ave., San Bruno, CA 94066, USA.
|
||||
|
||||
Wenn Sie eine unserer mit einem YouTube - Plugin ausgestatteten Seiten besuchen, wird eine Verbindung zu den Servern von YouTube hergestellt.Dabei wird dem YouTube - Server mitgeteilt, welche unserer Seiten Sie besucht haben.
|
||||
@ -177,6 +178,7 @@ Die Nutzung von YouTube erfolgt im Interesse einer ansprechenden Darstellung uns
|
||||
Weitere Informationen zum Umgang mit Nutzerdaten finden Sie in der Datenschutzerklärung von YouTube unter: https://www.google.de/intl/de/policies/privacy.
|
||||
|
||||
</div>
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ import Privacy from '../Privacy';
|
||||
import Login from '../User/Login';
|
||||
import Account from '../User/Account';
|
||||
import MyBadges from '../User/MyBadges';
|
||||
|
||||
import News from '../News'
|
||||
|
||||
class Routes extends Component {
|
||||
|
||||
@ -36,7 +36,7 @@ class Routes extends Component {
|
||||
<div style={{ margin: '0 22px' }}>
|
||||
<Switch>
|
||||
<PublicRoute path="/" exact>
|
||||
<Home/>
|
||||
<Home />
|
||||
</PublicRoute>
|
||||
{/* Tutorials */}
|
||||
<PublicRoute path="/tutorial" exact>
|
||||
@ -61,10 +61,10 @@ class Routes extends Component {
|
||||
</PublicRoute>
|
||||
{/* User-Projects */}
|
||||
<PrivateRoute path="/project" exact>
|
||||
<ProjectHome/>
|
||||
<ProjectHome />
|
||||
</PrivateRoute>
|
||||
<PrivateRoute path="/project/:projectId" exact>
|
||||
<Project/>
|
||||
<Project />
|
||||
</PrivateRoute>
|
||||
{/* User */}
|
||||
<IsLoggedRoute path="/user/login" exact>
|
||||
@ -87,10 +87,14 @@ class Routes extends Component {
|
||||
<PublicRoute path="/privacy" exact>
|
||||
<Privacy />
|
||||
</PublicRoute>
|
||||
<PublicRoute path="/news" exact>
|
||||
<News />
|
||||
</PublicRoute>
|
||||
{/* Not Found */}
|
||||
<PublicRoute>
|
||||
<NotFound />
|
||||
</PublicRoute>
|
||||
|
||||
</Switch>
|
||||
</div>
|
||||
);
|
||||
|
57
src/components/Tour.js
Normal file
57
src/components/Tour.js
Normal file
@ -0,0 +1,57 @@
|
||||
import * as Blockly from 'blockly/core';
|
||||
|
||||
export const home = () => {
|
||||
return [
|
||||
{
|
||||
selector: ".wrapper",
|
||||
content: `${Blockly.Msg.hometour_wrapper}`,
|
||||
},
|
||||
{
|
||||
selector: ".blocklyWindow",
|
||||
content: `${Blockly.Msg.hometour_blocklyWindow}`,
|
||||
},
|
||||
{
|
||||
selector: ".blocklyToolboxDiv",
|
||||
content: `${Blockly.Msg.hometour_blocklyToolboxDiv}`,
|
||||
},
|
||||
{
|
||||
selector: '.workspaceFunc',
|
||||
content: `${Blockly.Msg.hometour_workspaceFunc}`,
|
||||
},
|
||||
{
|
||||
selector: ".compileBlocks",
|
||||
content: `${Blockly.Msg.hometour_compileBlocks}`,
|
||||
},
|
||||
{
|
||||
selector: ".shareBlocks",
|
||||
content: `${Blockly.Msg.hometour_shareBlocks}`,
|
||||
},
|
||||
{
|
||||
selector: ".showCode",
|
||||
content: `${Blockly.Msg.hometour_showCode}`,
|
||||
},
|
||||
{
|
||||
selector: ".MenuButton",
|
||||
content: `${Blockly.Msg.hometour_menuButton}`,
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
export const assessment = () => {
|
||||
return [
|
||||
// to be continued...
|
||||
|
||||
{
|
||||
selector: '.assessmentDiv',
|
||||
content: `${Blockly.Msg.assessmenttour_assessmentDiv}`
|
||||
},
|
||||
{
|
||||
selector: '.injectionDiv',
|
||||
content: `${Blockly.Msg.assessmenttour_injectionDiv}`
|
||||
},
|
||||
{
|
||||
selector: '.solutionCheck',
|
||||
content: `${Blockly.Msg.assessmenttour_solutionCheck}`
|
||||
}
|
||||
];
|
||||
};
|
@ -33,7 +33,7 @@ class Assessment extends Component {
|
||||
var statusTask = status.tasks[taskIndex];
|
||||
|
||||
return (
|
||||
<div style={{ width: '100%' }}>
|
||||
<div className="assessmentDiv" style={{ width: '100%' }}>
|
||||
<Typography variant='h4' style={{ float: 'left', marginBottom: '5px', height: '40px', display: 'table' }}>{currentTask.headline}</Typography>
|
||||
<div style={{ float: 'right', height: '40px' }}><WorkspaceFunc assessment /></div>
|
||||
<Grid container spacing={2} style={{ marginBottom: '5px' }}>
|
||||
|
@ -64,7 +64,7 @@ class HintTutorialExists extends Component {
|
||||
button={Blockly.Msg.button_close}
|
||||
>
|
||||
<div>
|
||||
{Blockly.Msg.messages_newblockly_text}<Link to="/tutorial" className={this.props.classes.link}>test</Link>
|
||||
{Blockly.Msg.messages_newblockly_text}<Link to="/news" className={this.props.classes.link}>Blockly News</Link>
|
||||
</div>
|
||||
<FormControlLabel
|
||||
style={{ marginTop: '20px' }}
|
||||
|
@ -61,7 +61,7 @@ class SolutionCheck extends Component {
|
||||
<div>
|
||||
<Tooltip title={Blockly.Msg.tooltip_check_solution} arrow>
|
||||
<IconButton
|
||||
className={this.props.classes.compile}
|
||||
className={`solutionCheck ${this.props.classes.compile}`}
|
||||
style={{ width: '40px', height: '40px', marginRight: '5px' }}
|
||||
onClick={() => this.check()}
|
||||
>
|
||||
|
@ -122,7 +122,7 @@ class Compile extends Component {
|
||||
{this.props.iconButton ?
|
||||
<Tooltip title={Blockly.Msg.tooltip_compile_code} arrow style={{ marginRight: '5px' }}>
|
||||
<IconButton
|
||||
className={this.props.classes.iconButton}
|
||||
className={`compileBlocks ${this.props.classes.iconButton}`}
|
||||
onClick={() => this.compile()}
|
||||
>
|
||||
<FontAwesomeIcon icon={faClipboardCheck} size="l" />
|
||||
|
@ -44,7 +44,7 @@ class DownloadProject extends Component {
|
||||
<div style={this.props.style}>
|
||||
<Tooltip title={Blockly.Msg.tooltip_download_project} arrow>
|
||||
<IconButton
|
||||
className={this.props.classes.button}
|
||||
className={`saveBlocks ${this.props.classes.button}`}
|
||||
onClick={() => this.downloadXmlFile()}
|
||||
>
|
||||
<FontAwesomeIcon icon={faFileDownload} size="xs" />
|
||||
|
@ -95,7 +95,7 @@ class WorkspaceFunc extends Component {
|
||||
<div style={this.props.style}>
|
||||
<Tooltip title={Blockly.Msg.tooltip_share_project} arrow>
|
||||
<IconButton
|
||||
className={this.props.classes.button}
|
||||
className={`shareBlocks ${this.props.classes.button}`}
|
||||
onClick={() => this.shareBlocks()}
|
||||
>
|
||||
<FontAwesomeIcon icon={faShareAlt} size="xs" />
|
||||
|
Loading…
x
Reference in New Issue
Block a user