diff --git a/.gitignore b/.gitignore
index aefa1fb2c97..e7c3eb35348 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,3 +27,8 @@ npm-*
# for act
.secrets
launch.json
+
+# Environment variables
+.env
+.env.local
+.env.production
diff --git a/package-lock.json b/package-lock.json
index 6d3eab93279..4b5bb553f19 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,7 +12,7 @@
"@microbit/microbit-universal-hex": "^0.2.2",
"@splitsoftware/splitio-react": "^1.11.0",
"arraybuffer-loader": "^1.0.6",
- "artie-scratch-l10n": "3.18.5",
+ "artie-scratch-l10n": "3.19.000-artie",
"artie-scratch-vm": "4.8.39-artie",
"autoprefixer": "^9.0.1",
"balance-text": "^3.3.1",
@@ -4991,17 +4991,14 @@
}
},
"node_modules/artie-scratch-l10n": {
- "version": "3.18.5",
- "resolved": "https://registry.npmjs.org/artie-scratch-l10n/-/artie-scratch-l10n-3.18.5.tgz",
- "integrity": "sha512-UaVZinERR9WP3OgHps2Oa1rIPKI8Vkz7mm9zkr9cBC0qxENBxvQKr3Y/pxK9JPhpzh8iMFnbbz2jnEuzZjZDaQ==",
+ "version": "3.19.0-artie",
+ "resolved": "https://registry.npmjs.org/artie-scratch-l10n/-/artie-scratch-l10n-3.19.0-artie.tgz",
+ "integrity": "sha512-Amds1VCEJhn5OlxoZZ0/M7TxaiBFBlWwGUuzrXPcvG3mJaPGIIzlgKd/j4vWtyFuqc2p6ZnWViB9Ht+RV2bzdg==",
"license": "BSD-3-Clause",
"dependencies": {
- "@babel/cli": "^7.1.2",
- "@babel/core": "^7.1.2",
- "@transifex/api": "^4.3.0",
- "babel-plugin-react-intl": "^3.0.1",
- "download": "^8.0.0",
- "transifex": "^1.6.6"
+ "@transifex/api": "4.3.0",
+ "download": "8.0.0",
+ "transifex": "1.6.6"
},
"bin": {
"build-i18n-src": "scripts/build-i18n-src.js",
@@ -19095,8 +19092,6 @@
},
"node_modules/npm/node_modules/@npmcli/installed-package-contents/node_modules/npm-bundled": {
"version": "1.1.2",
- "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz",
- "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -19392,8 +19387,6 @@
},
"node_modules/npm/node_modules/bin-links/node_modules/npm-normalize-package-bin": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-2.0.0.tgz",
- "integrity": "sha512-awzfKUO7v0FscrSpRoogyNm0sajikhBWpU0QMrW09AMi9n1PoKU6WaIqUzuJSQnpciZZmJ/jMZ2Egfmb/9LiWQ==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -19681,8 +19674,6 @@
},
"node_modules/npm/node_modules/debug/node_modules/ms": {
"version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true,
"inBundle": true,
"license": "MIT"
@@ -20630,8 +20621,6 @@
},
"node_modules/npm/node_modules/node-gyp/node_modules/glob": {
"version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -20743,8 +20732,6 @@
},
"node_modules/npm/node_modules/npm-bundled/node_modules/npm-normalize-package-bin": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-2.0.0.tgz",
- "integrity": "sha512-awzfKUO7v0FscrSpRoogyNm0sajikhBWpU0QMrW09AMi9n1PoKU6WaIqUzuJSQnpciZZmJ/jMZ2Egfmb/9LiWQ==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -20811,8 +20798,6 @@
},
"node_modules/npm/node_modules/npm-packlist/node_modules/npm-normalize-package-bin": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-2.0.0.tgz",
- "integrity": "sha512-awzfKUO7v0FscrSpRoogyNm0sajikhBWpU0QMrW09AMi9n1PoKU6WaIqUzuJSQnpciZZmJ/jMZ2Egfmb/9LiWQ==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -20839,8 +20824,6 @@
},
"node_modules/npm/node_modules/npm-pick-manifest/node_modules/npm-normalize-package-bin": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-2.0.0.tgz",
- "integrity": "sha512-awzfKUO7v0FscrSpRoogyNm0sajikhBWpU0QMrW09AMi9n1PoKU6WaIqUzuJSQnpciZZmJ/jMZ2Egfmb/9LiWQ==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -21156,8 +21139,6 @@
},
"node_modules/npm/node_modules/read-package-json/node_modules/npm-normalize-package-bin": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-2.0.0.tgz",
- "integrity": "sha512-awzfKUO7v0FscrSpRoogyNm0sajikhBWpU0QMrW09AMi9n1PoKU6WaIqUzuJSQnpciZZmJ/jMZ2Egfmb/9LiWQ==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -21235,8 +21216,6 @@
},
"node_modules/npm/node_modules/rimraf/node_modules/glob": {
"version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -21317,8 +21296,6 @@
},
"node_modules/npm/node_modules/semver/node_modules/lru-cache": {
"version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dev": true,
"inBundle": true,
"license": "ISC",
@@ -23789,8 +23766,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/config-chain/node_modules/proto-list": {
"version": "1.2.4",
- "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
- "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==",
"inBundle": true,
"license": "ISC"
},
@@ -23838,8 +23813,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/fs-write-stream-atomic/node_modules/iferr": {
"version": "0.1.5",
- "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz",
- "integrity": "sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA==",
"inBundle": true,
"license": "MIT"
},
@@ -23870,8 +23843,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/fstream-npm/node_modules/fstream-ignore": {
"version": "1.0.5",
- "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.5.tgz",
- "integrity": "sha512-VVRuOs41VUqptEGiR0N5ZoWEcfGvbGRqLINyZAhHRnF3DH5wrqjNkYr3VbRoZnI41BZgO7zIVdiobc13TVI1ow==",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -23914,8 +23885,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/glob/node_modules/fs.realpath": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
"inBundle": true,
"license": "ISC"
},
@@ -24014,8 +23983,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/init-package-json/node_modules/promzard": {
"version": "0.3.0",
- "resolved": "https://registry.npmjs.org/promzard/-/promzard-0.3.0.tgz",
- "integrity": "sha512-JZeYqd7UAcHCwI+sTOeUDYkvEU+1bQ7iE0UT1MgB/tERkAPkesW46MrpIySzODi+owTjZtiF8Ay5j9m60KmMBw==",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -24038,8 +24005,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/lru-cache/node_modules/pseudomap": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
- "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==",
"inBundle": true,
"license": "ISC"
},
@@ -24075,8 +24040,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/minimatch/node_modules/brace-expansion/node_modules/concat-map": {
"version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"inBundle": true,
"license": "MIT"
},
@@ -24093,8 +24056,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/mkdirp/node_modules/minimist": {
"version": "0.0.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
- "integrity": "sha512-miQKw5Hv4NS1Psg2517mV4e4dYNaO3++hjAvLOAzKqZ61rH8NS1SK+vbfBWZ5PY/Me/bEWhUwqMghEW5Fb9T7Q==",
"inBundle": true,
"license": "MIT"
},
@@ -24126,8 +24087,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/node-gyp/node_modules/semver": {
"version": "5.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
- "integrity": "sha512-mfmm3/H9+67MCVix1h+IXTpDwL6710LyHuk7+cWC9T1mE0qz4iHhh6r4hU2wrIT9iTsAAC2XQRvfblL028cpLw==",
"inBundle": true,
"license": "ISC",
"bin": {
@@ -24167,8 +24126,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/normalize-package-data/node_modules/is-builtin-module": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
- "integrity": "sha512-C2wz7Juo5pUZTFQVer9c+9b4qw3I5T/CHQxQyhVu7BJel6C22FmsLIWsdseYyOw6xz9Pqy9eJWSkQ7+3iN1HVw==",
"inBundle": true,
"license": "MIT",
"dependencies": {
@@ -24262,36 +24219,26 @@
},
"node_modules/publish/node_modules/npm/node_modules/npm-registry-client/node_modules/concat-stream/node_modules/readable-stream/node_modules/core-util-is": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
- "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==",
"inBundle": true,
"license": "MIT"
},
"node_modules/publish/node_modules/npm/node_modules/npm-registry-client/node_modules/concat-stream/node_modules/readable-stream/node_modules/isarray": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
"inBundle": true,
"license": "MIT"
},
"node_modules/publish/node_modules/npm/node_modules/npm-registry-client/node_modules/concat-stream/node_modules/readable-stream/node_modules/process-nextick-args": {
"version": "1.0.7",
- "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
- "integrity": "sha512-yN0WQmuCX63LP/TMvAg31nvT6m4vDqJEiiv2CAZqWOGNWutc9DfDk1NPYYmKUFmaVM2UwDowH4u5AHWYP/jxKw==",
"inBundle": true,
"license": "MIT"
},
"node_modules/publish/node_modules/npm/node_modules/npm-registry-client/node_modules/concat-stream/node_modules/readable-stream/node_modules/string_decoder": {
"version": "0.10.31",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
- "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==",
"inBundle": true,
"license": "MIT"
},
"node_modules/publish/node_modules/npm/node_modules/npm-registry-client/node_modules/concat-stream/node_modules/readable-stream/node_modules/util-deprecate": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"inBundle": true,
"license": "MIT"
},
@@ -24338,15 +24285,11 @@
},
"node_modules/publish/node_modules/npm/node_modules/npmlog/node_modules/are-we-there-yet/node_modules/delegates": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
- "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==",
"inBundle": true,
"license": "MIT"
},
"node_modules/publish/node_modules/npm/node_modules/npmlog/node_modules/gauge": {
"version": "1.2.7",
- "resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.7.tgz",
- "integrity": "sha512-fVbU2wRE91yDvKUnrIaQlHKAWKY5e08PmztCrwuH5YVQ+Z/p3d0ny2T48o6uvAAXHIUnfaQdHkmxYbQft1eHVA==",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -24584,43 +24527,31 @@
},
"node_modules/publish/node_modules/npm/node_modules/readable-stream/node_modules/buffer-shims": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz",
- "integrity": "sha512-Zy8ZXMyxIT6RMTeY7OP/bDndfj6bwCan7SS98CEndS6deHwWPpseeHlwarNcBim+etXnF9HBc1non5JgDaJU1g==",
"inBundle": true,
"license": "MIT"
},
"node_modules/publish/node_modules/npm/node_modules/readable-stream/node_modules/core-util-is": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
- "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==",
"inBundle": true,
"license": "MIT"
},
"node_modules/publish/node_modules/npm/node_modules/readable-stream/node_modules/isarray": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
"inBundle": true,
"license": "MIT"
},
"node_modules/publish/node_modules/npm/node_modules/readable-stream/node_modules/process-nextick-args": {
"version": "1.0.7",
- "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
- "integrity": "sha512-yN0WQmuCX63LP/TMvAg31nvT6m4vDqJEiiv2CAZqWOGNWutc9DfDk1NPYYmKUFmaVM2UwDowH4u5AHWYP/jxKw==",
"inBundle": true,
"license": "MIT"
},
"node_modules/publish/node_modules/npm/node_modules/readable-stream/node_modules/string_decoder": {
"version": "0.10.31",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
- "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==",
"inBundle": true,
"license": "MIT"
},
"node_modules/publish/node_modules/npm/node_modules/readable-stream/node_modules/util-deprecate": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"inBundle": true,
"license": "MIT"
},
@@ -24668,8 +24599,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/aws-sign2": {
"version": "0.6.0",
- "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
- "integrity": "sha512-JnJpAS0p9RmixkOvW2XwDxxzs1bd4/VAGIl6Q0EC5YOo+p+hqIhtDhn/nmFnB/xUNXbLkpE2mOjgVIBRKD4xYw==",
"inBundle": true,
"license": "Apache-2.0",
"engines": {
@@ -24683,8 +24612,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/bl": {
"version": "1.1.2",
- "resolved": "https://registry.npmjs.org/bl/-/bl-1.1.2.tgz",
- "integrity": "sha512-uVVYHEQk+OuWvCi5U+iquVXvvGCWXKawjwELIR2XMLsqfV/e2sGDClVBs8OlGIgGsStPRY/Es311YKYIlYCWAg==",
"inBundle": true,
"license": "MIT",
"dependencies": {
@@ -24693,8 +24620,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/bl/node_modules/readable-stream": {
"version": "2.0.6",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz",
- "integrity": "sha512-TXcFfb63BQe1+ySzsHZI/5v1aJPCShfqvWJ64ayNImXMsN1Cd0YGk/wm8KB7/OeessgPc9QvS9Zou8QTkFzsLw==",
"inBundle": true,
"license": "MIT",
"dependencies": {
@@ -24708,43 +24633,31 @@
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/bl/node_modules/readable-stream/node_modules/core-util-is": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
- "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==",
"inBundle": true,
"license": "MIT"
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/bl/node_modules/readable-stream/node_modules/isarray": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
"inBundle": true,
"license": "MIT"
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/bl/node_modules/readable-stream/node_modules/process-nextick-args": {
"version": "1.0.7",
- "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
- "integrity": "sha512-yN0WQmuCX63LP/TMvAg31nvT6m4vDqJEiiv2CAZqWOGNWutc9DfDk1NPYYmKUFmaVM2UwDowH4u5AHWYP/jxKw==",
"inBundle": true,
"license": "MIT"
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/bl/node_modules/readable-stream/node_modules/string_decoder": {
"version": "0.10.31",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
- "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==",
"inBundle": true,
"license": "MIT"
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/bl/node_modules/readable-stream/node_modules/util-deprecate": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"inBundle": true,
"license": "MIT"
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/caseless": {
"version": "0.11.0",
- "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz",
- "integrity": "sha512-ODLXH644w9C2fMPAm7bMDQ3GRvipZWZfKc+8As6hIadRIelE0n0xZuN38NS6kiK3KPEVrpymmQD8bvncAHWQkQ==",
"inBundle": true,
"license": "Apache-2.0"
},
@@ -24761,8 +24674,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/combined-stream/node_modules/delayed-stream": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
- "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"inBundle": true,
"license": "MIT",
"engines": {
@@ -24776,8 +24687,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/forever-agent": {
"version": "0.6.1",
- "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
- "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==",
"inBundle": true,
"license": "Apache-2.0",
"engines": {
@@ -24804,8 +24713,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/har-validator": {
"version": "2.0.6",
- "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz",
- "integrity": "sha512-P6tFV+wCcUL3nbyTDAvveDySfbhy0XkDtAIfZP6HITjM2WUsiPna/Eg1Yy93SFXvahqoX+kt0n+6xlXKDXYowA==",
"inBundle": true,
"license": "ISC",
"dependencies": {
@@ -24823,8 +24730,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/har-validator/node_modules/chalk": {
"version": "1.1.3",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
- "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==",
"inBundle": true,
"license": "MIT",
"dependencies": {
@@ -24840,8 +24745,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/har-validator/node_modules/chalk/node_modules/ansi-styles": {
"version": "2.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
- "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==",
"inBundle": true,
"license": "MIT",
"engines": {
@@ -24850,8 +24753,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/har-validator/node_modules/chalk/node_modules/escape-string-regexp": {
"version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
"inBundle": true,
"license": "MIT",
"engines": {
@@ -24860,8 +24761,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/har-validator/node_modules/chalk/node_modules/has-ansi": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
- "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==",
"inBundle": true,
"license": "MIT",
"dependencies": {
@@ -24873,8 +24772,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/har-validator/node_modules/chalk/node_modules/supports-color": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
- "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==",
"inBundle": true,
"license": "MIT",
"engines": {
@@ -24915,8 +24812,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/har-validator/node_modules/is-my-json-valid/node_modules/generate-object-property": {
"version": "1.2.0",
- "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
- "integrity": "sha512-TuOwZWgJ2VAMEGJvAyPWvpqxSANF0LDpmyHauMjFYzaACvn+QTT/AZomvPCzVBV7yDN3OmwHQ5OvHaeLKre3JQ==",
"inBundle": true,
"license": "MIT",
"dependencies": {
@@ -24925,8 +24820,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/har-validator/node_modules/is-my-json-valid/node_modules/generate-object-property/node_modules/is-property": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
- "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==",
"inBundle": true,
"license": "MIT"
},
@@ -24948,8 +24841,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/har-validator/node_modules/pinkie-promise": {
"version": "2.0.1",
- "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
- "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==",
"inBundle": true,
"license": "MIT",
"dependencies": {
@@ -24961,8 +24852,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/har-validator/node_modules/pinkie-promise/node_modules/pinkie": {
"version": "2.0.4",
- "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
- "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==",
"inBundle": true,
"license": "MIT",
"engines": {
@@ -24971,8 +24860,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/hawk": {
"version": "3.1.3",
- "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
- "integrity": "sha512-X8xbmTc1cbPXcQV4WkLcRMALuyoxhfpFATmyuCxJPOAvrDS4DNnsTAOmKUxMTOWU6TzrTOkxPKwIx5ZOpJVSrg==",
"inBundle": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -25000,8 +24887,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/hawk/node_modules/cryptiles": {
"version": "2.0.5",
- "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
- "integrity": "sha512-FFN5KwpvvQTTS5hWPxrU8/QE4kQUc6uwZcrnlMBN82t1MgAtq8mnoDwINBly9Tdr02seeIIhtdF+UH1feBYGog==",
"inBundle": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -25023,8 +24908,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/hawk/node_modules/sntp": {
"version": "1.0.9",
- "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
- "integrity": "sha512-7bgVOAnPj3XjrKY577S+puCKGCRlUrcrEdsMeRXlg9Ghf5df/xNi6sONUa43WrHUd3TjJBF7O04jYoiY0FVa0A==",
"inBundle": true,
"dependencies": {
"hoek": "2.x.x"
@@ -25035,8 +24918,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/http-signature": {
"version": "1.1.1",
- "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
- "integrity": "sha512-iUn0NcRULlDGtqNLN1Jxmzayk8ogm7NToldASyZBpM2qggbphjXzNOiw3piN8tgz+e/DRs6X5gAzFwTI6BCRcg==",
"inBundle": true,
"license": "MIT",
"dependencies": {
@@ -25051,8 +24932,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/http-signature/node_modules/assert-plus": {
"version": "0.2.0",
- "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
- "integrity": "sha512-u1L0ZLywRziOVjUhRxI0Qg9G+4RnFB9H/Rq40YWn0dieDgO7vAYeJz6jKAO6t/aruzlDFLAPkQTT87e+f8Imaw==",
"inBundle": true,
"license": "MIT",
"engines": {
@@ -25184,22 +25063,16 @@
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/is-typedarray": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
- "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==",
"inBundle": true,
"license": "MIT"
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/isstream": {
"version": "0.1.2",
- "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
- "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==",
"inBundle": true,
"license": "MIT"
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/json-stringify-safe": {
"version": "5.0.1",
- "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
- "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
"inBundle": true,
"license": "ISC"
},
@@ -25231,8 +25104,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/oauth-sign": {
"version": "0.8.2",
- "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
- "integrity": "sha512-VlF07iu3VV3+BTXj43Nmp6Irt/G7j/NgEctUS6IweH1RGhURjjCc2NWtzXFPXXWWfc7hgbXQdtiQu2LGp6MxUg==",
"inBundle": true,
"license": "Apache-2.0",
"engines": {
@@ -25262,8 +25133,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/request/node_modules/tunnel-agent": {
"version": "0.4.3",
- "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz",
- "integrity": "sha512-e0IoVDWx8SDHc/hwFTqJDQ7CCDTEeGhmcT9jkWJjoGQSpgBz20nAMr80E3Tpk7PatJ1b37DQDgJR3CNSzcMOZQ==",
"inBundle": true,
"license": "Apache-2.0",
"engines": {
@@ -25340,8 +25209,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/sha/node_modules/readable-stream/node_modules/string_decoder": {
"version": "0.10.31",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
- "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==",
"inBundle": true,
"license": "MIT"
},
@@ -25462,8 +25329,6 @@
},
"node_modules/publish/node_modules/npm/node_modules/validate-npm-package-name/node_modules/builtins": {
"version": "0.0.7",
- "resolved": "https://registry.npmjs.org/builtins/-/builtins-0.0.7.tgz",
- "integrity": "sha512-T8uCGKc0/2aLVt6omt8JxDRBoWEMkku+wFesxnhxnt4NygVZG99zqxo7ciK8eebszceKamGoUiLdkXCgGQyrQw==",
"inBundle": true,
"license": "MIT"
},
diff --git a/package.json b/package.json
index 389ece8d160..0fea0cbda37 100644
--- a/package.json
+++ b/package.json
@@ -33,7 +33,9 @@
},
"dependencies": {
"@microbit/microbit-universal-hex": "^0.2.2",
+ "@splitsoftware/splitio-react": "^1.11.0",
"arraybuffer-loader": "^1.0.6",
+ "artie-scratch-vm": "4.8.39-artie",
"autoprefixer": "^9.0.1",
"balance-text": "^3.3.1",
"base64-loader": "^1.0.0",
@@ -50,6 +52,7 @@
"fastestsmallesttextencoderdecoder": "^1.0.22",
"get-float-time-domain-data": "^0.1.0",
"get-user-media-promise": "^1.1.4",
+ "html2canvas": "^1.4.1",
"immutable": "^3.8.2",
"intl": "^1.2.5",
"js-base64": "^2.4.9",
@@ -83,25 +86,21 @@
"react-tooltip": "^4.5.1",
"react-virtualized": "^9.20.1",
"redux": "^3.7.2",
+ "redux-logger": "^3.0.6",
"redux-throttle": "^0.1.1",
"scratch-audio": "^1.0.0",
"scratch-blocks": "^1.1.6",
- "artie-scratch-l10n": "3.18.5",
+ "artie-scratch-l10n": "3.19.000-artie",
"scratch-paint": "^2.2.151",
"scratch-render": "^1.0.233",
"scratch-render-fonts": "^1.0.2",
"scratch-storage": "^2.3.1",
"scratch-svg-renderer": "^2.3.102",
- "artie-scratch-vm": "4.8.39-artie",
"startaudiocontext": "^1.2.1",
"style-loader": "4.0.0",
"to-style": "^1.3.3",
"wav-encoder": "^1.3.0",
- "xhr": "^2.5.0",
-
- "redux-logger": "^3.0.6",
- "html2canvas": "^1.4.1",
- "@splitsoftware/splitio-react": "^1.11.0"
+ "xhr": "^2.5.0"
},
"peerDependencies": {
"react": "^16.0.0",
diff --git a/src/components/artie-help/artie-loading-overlay.css b/src/components/artie-help/artie-loading-overlay.css
new file mode 100644
index 00000000000..d950f26a775
--- /dev/null
+++ b/src/components/artie-help/artie-loading-overlay.css
@@ -0,0 +1,30 @@
+@import "../../css/colors.css";
+
+.artie-loading-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100vw;
+ height: 100vh;
+ background-color: rgba(0, 0, 0, 0.4);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 10001; /* por encima de popups y menús */
+}
+
+.artie-loading-overlay__content {
+ background: hsla(215, 50%, 90%, 1); /* equivalente a $ui-tertiary */
+ border-radius: 12px;
+ padding: 24px 32px;
+ box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 12px;
+}
+
+.artie-loading-overlay__text {
+ color: hsla(0, 100%, 100%, 1); /* equivalente a $ui-white */
+ font-weight: bold;
+}
diff --git a/src/components/artie-help/artie-loading-overlay.jsx b/src/components/artie-help/artie-loading-overlay.jsx
new file mode 100644
index 00000000000..55be0258b78
--- /dev/null
+++ b/src/components/artie-help/artie-loading-overlay.jsx
@@ -0,0 +1,38 @@
+/* eslint-disable no-multiple-empty-lines */
+import classNames from 'classnames';
+import React from 'react';
+import ReactDOM from 'react-dom';
+import PropTypes from 'prop-types';
+import {FormattedMessage} from 'react-intl';
+
+import Spinner from '../spinner/spinner.jsx';
+import styles from './artie-loading-overlay.css';
+
+const ArtieLoadingOverlay = ({
+ className
+}) => (
+ ReactDOM.createPortal(
+
,
+ document.body
+ )
+);
+
+ArtieLoadingOverlay.propTypes = {
+ className: PropTypes.string
+};
+
+export default ArtieLoadingOverlay; // EOF
diff --git a/src/components/menu-bar/menu-bar.jsx b/src/components/menu-bar/menu-bar.jsx
index c0988335f2b..b3b3be4dad4 100644
--- a/src/components/menu-bar/menu-bar.jsx
+++ b/src/components/menu-bar/menu-bar.jsx
@@ -119,8 +119,8 @@ import {
ARTIE_FLOW_EXERCISES_STATE,
ARTIE_FLOW_EXERCISE_STATEMENT_STATE,
ARTIE_FLOW_EMOTIONAL_STATE,
- artieChangeFlowState,
- ARTIE_FLOW_HELP_POPUP_STATE
+ ARTIE_FLOW_HELP_POPUP_STATE,
+ setArtieFlowState
} from '../../reducers/artie-flow.js';
import ArtieFlow from '../../containers/artie-flow.jsx';
import ArtieWebcamRecorder from '../../containers/artie-webcam-recorder.jsx';
@@ -128,6 +128,7 @@ import {ArtieExerciseStatementTooltip} from '../artie-exercises/artie-exercises-
import html2canvas from 'html2canvas';
import Spinner from '../spinner/spinner.jsx';
+import ArtieLoadingOverlay from '../artie-help/artie-loading-overlay.jsx';
const ariaMessages = defineMessages({
tutorials: {
@@ -236,6 +237,7 @@ class MenuBar extends React.Component {
// Setting the default SPLIT IO Flags values
this.artieEmotionalPopupFeature = '';
+ this.artieHelpPopupFeature = '';
}
componentDidMount () {
document.addEventListener('keydown', this.handleKeyPress);
@@ -395,6 +397,7 @@ class MenuBar extends React.Component {
{
- canvasUrl = canvas.toDataURL('image/png');
- sendBlockArtie(currentStudent, sprites, currentExercise, false, emotionalState, secondsHelpOpen,
- true, lastLogin, lastExerciseChange, canvasUrl, binary)
- .then(() => {
-
- // Stops the loading help and shows the popup
- fOnArtieLoadingExercise(false);
- fOnArtieExerciseSentPopupOpen(true);
- fOnArtieChangeFlowState(ARTIE_FLOW_EXERCISE_STATEMENT_STATE);
- });
- if (secondsHelpOpen > 0) {
- fOnArtieResetSecondsHelpOpen();
- }
- });
+ html2canvas(body)
+ .then(canvas => {
+ canvasUrl = canvas.toDataURL('image/png');
+ return sendBlockArtie(
+ currentStudent,
+ sprites,
+ currentExercise,
+ false,
+ emotionalState,
+ secondsHelpOpen,
+ true,
+ lastLogin,
+ lastExerciseChange,
+ canvasUrl,
+ binary
+ );
+ })
+ .then(() => {
+ // Éxito: mostramos popup y cambiamos de estado
+ fOnArtieExerciseSentPopupOpen(true);
+ })
+ .catch(() => {
+ // En caso de error, simplemente cerramos el overlay en finally
+ })
+ .finally(() => {
+ // Siempre detener la pantalla de carga y resetear contador si corresponde
+ fOnArtieLoadingExercise(false);
+ if (secondsHelpOpen > 0) {
+ fOnArtieResetSecondsHelpOpen();
+ }
+ });
};
- });
+ })
+ .catch(() => {
+ // Si falla la obtención del blob, aseguramos ocultar el overlay
+ this.props.onArtieLoadingExercise(false);
+ });
}
handleArtieLogout (){
this.props.onArtieLogout();
@@ -517,30 +539,56 @@ class MenuBar extends React.Component {
this.props.onArtieChangeFlowState(ARTIE_FLOW_EXERCISE_STATEMENT_STATE);
}
handleClickRequestEmotionalHelp (){
+ // Evita múltiples solicitudes mientras está cargando
+ if (this.props.artieExercises.loadingHelp) return;
+
this.props.onArtieShowHelpPopup(null, true);
-
+
if (this.artieEmotionalPopupFeature === 'on') {
- // We show the emotional just in case the flag is active
+ // We show the emotional popup just in the case the flag is active
this.props.onArtieChangeFlowState(ARTIE_FLOW_EMOTIONAL_STATE);
} else {
-
+ // Activamos pantalla de carga mientras esperamos la ayuda
+ this.props.onArtieLoadingHelp(true);
+
+ // Compute Split guard: if Help_Popup is OFF and the student interacts with the robot,
+ // we should NOT present the help popup; the robot tutor will provide the help instead.
+ const interactsWithRobot = Boolean(
+ // eslint-disable-next-line max-len
+ (this.props.artieLogin && this.props.artieLogin.currentStudent && this.props.artieLogin.currentStudent.interactsWithRobot) ||
+ (this.props.artieLogin && this.props.artieLogin.user && this.props.artieLogin.user.interactsWithRobot)
+ );
+ const hideByFeature = this.artieHelpPopupFeature === 'off' && interactsWithRobot;
+
// In case the the flag is off we just show the help popup
- sendBlockArtie(this.props.artieLogin.currentStudent, this.props.sprites,
- this.props.artieExercises.currentExercise, true, this.props.artieHelp.emotionalState,
- this.props.artieExercises.secondsHelpOpen, false, this.props.artieLogin.lastLogin,
- this.props.artieExercises.lastExerciseChange, null, null)
+ sendBlockArtie(
+ this.props.artieLogin.currentStudent,
+ this.props.sprites,
+ this.props.artieExercises.currentExercise,
+ true,
+ this.props.artieHelp.emotionalState,
+ this.props.artieExercises.secondsHelpOpen,
+ false,
+ this.props.artieLogin.lastLogin,
+ this.props.artieExercises.lastExerciseChange,
+ null,
+ null
+ )
.then(responseBodyObject => {
-
// If the response has a solution distance object
if (responseBodyObject !== null && responseBodyObject.solutionDistance !== null){
this.props.onArtieHelpReceived(responseBodyObject.solutionDistance);
if (responseBodyObject.solutionDistance.totalDistance === 0){
this.props.onArtieChangeFlowState(ARTIE_FLOW_EXERCISE_STATEMENT_STATE);
- } else {
+ } else if (!hideByFeature) {
this.props.onArtieChangeFlowState(ARTIE_FLOW_HELP_POPUP_STATE);
}
}
-
+ })
+ .catch(() => {
+ // En caso de error, aseguramos ocultar el overlay
+ })
+ .finally(() => {
// Stops the loading help
this.props.onArtieLoadingHelp(false);
});
@@ -553,6 +601,9 @@ class MenuBar extends React.Component {
if (featureFlag === 'Emotional_Popup') {
this.artieEmotionalPopupFeature = value;
}
+ if (featureFlag === 'Help_Popup'){
+ this.artieHelpPopupFeature = value;
+ }
}
render () {
const saveNowMessage = (
@@ -596,6 +647,15 @@ class MenuBar extends React.Component {
{remixMessage}
);
+ // Compute small helpers to keep JSX lines short and readable
+ const user = this.props.artieLogin && this.props.artieLogin.user;
+ const isLoggedIn = Boolean(user);
+ const isStudent = isLoggedIn && user.role === 0;
+ const isTeacher = isLoggedIn && user.role === 1;
+ const hasCurrentStudent = Boolean(this.props.artieLogin && this.props.artieLogin.currentStudent);
+ const hasExercise = Boolean(this.props.artieExercises && this.props.artieExercises.currentExercise);
+ const isEvaluation = hasExercise && this.props.artieExercises.currentExercise.evaluation;
+ const showLogin = !isLoggedIn || (isStudent && !hasCurrentStudent);
// Show the About button only if we have a handler for it (like in the desktop app)
const aboutButton = this.buildAboutMenu(this.props.onClickAbout);
return (
@@ -634,7 +694,7 @@ class MenuBar extends React.Component {
})}
onMouseUp={this.props.onClickFile}
>
-
+
-
+
-
+
-
+
) : null)}
- {this.props.canShare ? (
- (this.props.isShowingProject || this.props.isUpdating) && (
-
- {
- waitForUpdate => (
- {
- this.handleClickShare(waitForUpdate);
- }}
- /* eslint-enable react/jsx-no-bind */
- />
- )
- }
-
- )
- ) : (
- this.props.showComingSoon ? (
-
-
-
- ) : []
- )}
- {this.props.canRemix ? remixButton : []}
+ {this.props.canShare && (this.props.isShowingProject || this.props.isUpdating) ? (
+
+ {(waitForUpdate) => (
+ {
+ this.handleClickShare(waitForUpdate);
+ }}
+ /* eslint-enable react/jsx-no-bind */
+ />
+ )}
+
+ ) : (!this.props.canShare && this.props.showComingSoon ? (
+
+
+
+ ) : null)}
+ {this.props.canRemix ? remixButton : null}
- {this.props.enableCommunity ? (
- (this.props.isShowingProject || this.props.isUpdating) && (
-
- {
- waitForUpdate => (
- {
- this.handleClickSeeCommunity(waitForUpdate);
- }}
- /* eslint-enable react/jsx-no-bind */
- />
- )
- }
-
- )
+ {this.props.enableCommunity && (this.props.isShowingProject || this.props.isUpdating) ? (
+
+ {(waitForUpdate) => (
+ {
+ this.handleClickSeeCommunity(waitForUpdate);
+ }}
+ /* eslint-enable react/jsx-no-bind */
+ />
+ )}
+
) : (this.props.showComingSoon ? (
- ) : [])}
+ ) : null)}
@@ -891,14 +941,15 @@ class MenuBar extends React.Component {
onRequestClose={this.props.onRequestCloseArtie}
>
- {this.props.artieLogin.user == null || (this.props.artieLogin.user.role === 0 && this.props.artieLogin.currentStudent == null) ?
+ {showLogin ? (
:
+
+ ) : (
- }
+ )}
- {this.props.artieLogin.user !== null && this.props.artieLogin.user.role === 1 && this.props.artieExercises.currentExercise !== null ?
+ {isTeacher && hasExercise ? (
- :
- null
- }
- {this.props.artieLogin.user !== null && this.props.artieLogin.user.role === 0 && this.props.artieLogin.currentStudent !== null &&
- this.props.artieExercises.currentExercise !== null && !this.props.artieExercises.currentExercise.evaluation ?
+
+ ) : null}
+ {isStudent && hasCurrentStudent && hasExercise && !isEvaluation ? (
- :
- null
- }
- {this.props.artieLogin.user !== null && this.props.artieLogin.user.role === 0 && this.props.artieLogin.currentStudent !== null &&
- this.props.artieExercises.currentExercise !== null && !this.props.artieExercises.currentExercise.evaluation ?
+
+ ) : null}
+ {isStudent && hasCurrentStudent && hasExercise && !isEvaluation ? (
- {this.props.artieExercises.loadingExercise ?
+ {this.props.artieExercises.loadingExercise ? (
:
- null }
+ />
+ ) : null}
- :
- null
- }
+
+ ) : null}
- {this.props.artieLogin.user !== null &&
- (
- (this.props.artieLogin.user.role === 0 && this.props.artieLogin.currentStudent !== null) ||
- this.props.artieLogin.user.role === 1
- ) ?
+ {isLoggedIn && ((isStudent && hasCurrentStudent) || isTeacher) ?
- {this.props.artieExercises.currentExercise !== null ?
+ {hasExercise ? (
- :
+
+ ) : (
- }
+ )}
- { this.props.artieLogin !== null && this.props.artieLogin.user !== null && this.props.artieLogin.user.role === 0 &&
- this.props.artieExercises.currentExercise !== null && this.props.artieExercises.currentExercise.evaluation ?
+ { isStudent && hasExercise && isEvaluation ? (
:
- null }
+ />
+ ) : null }
- { this.props.artieLogin !== null && this.props.artieLogin.user !== null && this.props.artieLogin.user.role === 0 &&
- this.props.artieExercises.currentExercise !== null && !this.props.artieExercises.currentExercise.evaluation ?
+ { isStudent && hasExercise && !isEvaluation ? (
- :
- null }
+
+ ) : null }
- { this.props.artieLogin !== null && this.props.artieLogin.user !== null && this.props.artieLogin.user.role === 0 &&
- this.props.artieExercises.currentExercise !== null && this.props.artieExercises.currentExercise.evaluation ?
+ { isStudent && hasExercise && isEvaluation ? (
- :
+
+ ) : (
@@ -1052,7 +1099,7 @@ class MenuBar extends React.Component {
onClick={this.handleShowPopupStatement}
/>
- }
+ )}
:
null
}
@@ -1068,6 +1115,7 @@ class MenuBar extends React.Component {
@@ -1099,6 +1147,7 @@ class MenuBar extends React.Component {
@@ -1173,6 +1222,7 @@ class MenuBar extends React.Component {
@@ -1190,6 +1240,7 @@ class MenuBar extends React.Component {
{'scratch-cat'}
@@ -1197,18 +1248,30 @@ class MenuBar extends React.Component {
- ) : []}
+ ) : null}
)}
{aboutButton}
-
-
+
+ {(
+ this.props.artieExercises.loadingHelp ||
+ this.props.artieExercises.loadingExercise
+ ) ? (
+
+ ) : null}
+
+ {/* Propagate Split flag down so ArtieFlow/ArtieHelp can decide visibility */}
+
);
@@ -1273,6 +1336,8 @@ MenuBar.propTypes = {
onClickSave: PropTypes.func,
onClickSaveAsCopy: PropTypes.func,
onClickSettings: PropTypes.func,
+ // Added: validate handler used to open the Artie login menu item
+ onActivateArtieLogin: PropTypes.func.isRequired,
onLogOut: PropTypes.func,
onOpenRegistration: PropTypes.func,
onOpenTipLibrary: PropTypes.func,
@@ -1309,7 +1374,17 @@ MenuBar.propTypes = {
onArtieEvaluationStop: PropTypes.func.isRequired,
onArtieHelpReceived: PropTypes.func.isRequired,
onArtieLoadingHelp: PropTypes.func.isRequired,
- onArtieResetSecondsHelpOpen: PropTypes.func.isRequired
+ onArtieResetSecondsHelpOpen: PropTypes.func.isRequired,
+ // Añadidos para validación
+ onArtieLoadingSolution: PropTypes.func.isRequired,
+ onArtieExerciseSentPopupOpen: PropTypes.func.isRequired,
+ saveProjectSb3: PropTypes.func.isRequired,
+ onClickArtie: PropTypes.func.isRequired,
+ onRequestCloseArtie: PropTypes.func.isRequired,
+ artieLogin: PropTypes.object.isRequired,
+ artieExercises: PropTypes.object.isRequired,
+ artieHelp: PropTypes.object.isRequired,
+ sprites: PropTypes.object.isRequired
};
MenuBar.defaultProps = {
@@ -1392,7 +1467,7 @@ const mapDispatchToProps = dispatch => ({
onArtieShowHelpPopup: (id, showHelpPopup) => dispatch(artieShowHelpPopup(id, showHelpPopup)),
onClickArtie: () => dispatch(openArtieMenu()),
onRequestCloseArtie: () => dispatch(closeArtieMenu()),
- onArtieChangeFlowState: state => dispatch(artieChangeFlowState(state))
+ onArtieChangeFlowState: state => dispatch(setArtieFlowState(state))
});
export default compose(
diff --git a/src/components/menu-bar/request-help-button.css b/src/components/menu-bar/request-help-button.css
index 5f2cd606348..ba76cdbe962 100644
--- a/src/components/menu-bar/request-help-button.css
+++ b/src/components/menu-bar/request-help-button.css
@@ -1,5 +1,10 @@
@import "../../css/colors.css";
.select-exercise-button {
- background: $data-primary;
+ background: hsla(30, 100%, 55%, 1); /* equivalente a $data-primary */
+}
+
+.disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
}
diff --git a/src/components/menu-bar/request-help-button.jsx b/src/components/menu-bar/request-help-button.jsx
index 535ebf4e141..b4813c8b98e 100644
--- a/src/components/menu-bar/request-help-button.jsx
+++ b/src/components/menu-bar/request-help-button.jsx
@@ -9,14 +9,18 @@ import styles from './request-help-button.css';
const RequestHelpButton = ({
className,
- onClick
+ onClick,
+ disabled
}) => (