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 { About { - 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} > - + File - + Open - + Edit - + Open ) : 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 ? ( - {this.props.artieExercises.loadingSolution ? + {this.props.artieExercises.loadingSolution ? ( : - null } + /> + ) : null} - : - 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.loadingHelp ? + {this.props.artieExercises.loadingHelp ? ( : - null } + /> + ) : null } - : - 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 { Help @@ -1099,6 +1147,7 @@ class MenuBar extends React.Component { My Stuff @@ -1173,6 +1222,7 @@ class MenuBar extends React.Component { My Stuff @@ -1190,6 +1240,7 @@ class MenuBar extends React.Component { Profile {'scratch-cat'} @@ -1197,18 +1248,30 @@ class MenuBar extends React.Component { Open - ) : []} + ) : 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 }) => (