From 539e54afe856b2888e6e9a4b8e6d240ae8eacfc0 Mon Sep 17 00:00:00 2001 From: James Mead Date: Tue, 13 Jul 2021 10:49:23 +0100 Subject: [PATCH 01/13] Allow MenuBar to be hidden The MenuBar is quite specific to the canonical version of the online Scratch editor [1]. We want to make use of the scratch-gui package without displaying the MenuBar. Since the height of the menu bar is hard-coded as a CSS variable, I've had to override the height calculation for the body wrapper when the menu bar is not visible. Ideally the height of the menu bar wouldn't be hard-coded and this wouldn't be necessary. [1]: https://scratch.mit.edu/projects/editor --- src/components/gui/gui.css | 6 +++- src/components/gui/gui.jsx | 72 +++++++++++++++++++++----------------- 2 files changed, 45 insertions(+), 33 deletions(-) diff --git a/src/components/gui/gui.css b/src/components/gui/gui.css index eeb3989a1fe..565e55b8000 100644 --- a/src/components/gui/gui.css +++ b/src/components/gui/gui.css @@ -7,8 +7,12 @@ } .body-wrapper { - height: calc(100% - $menu-bar-height); background-color: $ui-primary; + height: calc(100% - $menu-bar-height); +} + +.body-wrapper-without-menu-bar { + height: 100%; } .body-wrapper * { diff --git a/src/components/gui/gui.jsx b/src/components/gui/gui.jsx index a446048989c..03180042826 100644 --- a/src/components/gui/gui.jsx +++ b/src/components/gui/gui.jsx @@ -89,6 +89,7 @@ const GUIComponent = props => { isTelemetryEnabled, loading, logo, + menuBarHidden, renderLogin, onClickAbout, onClickAccountNav, @@ -140,6 +141,9 @@ const GUIComponent = props => { return ({isFullSize => { const stageSize = resolveStageSize(stageSizeMode, isFullSize); + const boxStyles = classNames(styles.bodyWrapper, { + [styles.bodyWrapperWithoutMenuBar]: menuBarHidden + }); return isPlayerOnly ? ( { onRequestClose={onRequestCloseBackdropLibrary} /> ) : null} - - + {!menuBarHidden && + + } + Date: Tue, 6 Jul 2021 09:53:17 +0100 Subject: [PATCH 02/13] Configure CircleCI builds to deploy code-club-world branch to GH Pages This is specific to the RPF CodeClubWorld app and should not be merged into the main "develop" branch or pushed to the upstream repo. I don't think we need the deploy-npm or push-translations workflows. The `npm run deploy -- -e $CIRCLE_BRANCH` step in the deploy-gh-pages job appears to make use of the gh-pages `-e` option [1] to publish the changes to the gh-pages branch within a sub-directory named after the current branch. I've retained this functionality given that it may well be useful if we want to try out changes without affecting production. [1]: https://github.com/rschamp/gh-pages/commit/e0dd4eaa54276a8dac2be16fd4c75a233bdd582c#diff-558572b6f7bd7068bbbd3db502651a5a313bfc3901d72eb2995833592e4434edR30 --- .circleci/config.yml | 58 -------------------------------------------- 1 file changed, 58 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1a13f031d4d..bc120407fc9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -127,30 +127,6 @@ jobs: - store_test_results: path: test-results - deploy-npm: - <<: *defaults - environment: - NODE_OPTIONS: --max-old-space-size=4000 - steps: - - *restore_git_cache - - *restore_dist_cache - - checkout - - run: | - echo export RELEASE_VERSION="0.1.0-prerelease.$(date +'%Y%m%d%H%M%S')" >> $BASH_ENV - echo export NPM_TAG=latest >> $BASH_ENV - if [ "$CIRCLE_BRANCH" == "master" ] - then echo export NPM_TAG=stable >> $BASH_ENV - fi - if [[ "$CIRCLE_BRANCH" == hotfix/* ]] # double brackets are important for matching the wildcard - then echo export NPM_TAG=hotfix >> $BASH_ENV - fi - - run: npm version --no-git-tag-version $RELEASE_VERSION - - run: | - npm set //registry.npmjs.org/:_authToken=$NPM_TOKEN - npm publish --tag $NPM_TAG - - run: git tag $RELEASE_VERSION - - run: git push $CIRCLE_REPOSITORY_URL $RELEASE_VERSION - deploy-gh-pages: <<: *defaults steps: @@ -162,31 +138,9 @@ jobs: git config --global user.email $(git log --pretty=format:"%ae" -n1) git config --global user.name $(git log --pretty=format:"%an" -n1) - run: npm run deploy -- -e $CIRCLE_BRANCH - push-translations: - <<: *defaults - steps: - - *restore_git_cache - - checkout - - *restore_npm_cache - - run: npm run i18n:src - - run: npm run i18n:push workflows: version: 2 - push-translations: - triggers: - - schedule: - cron: 0 0 * * * # daily at 12 UTC, 8 ET - filters: - branches: - only: - - develop - jobs: - - setup - - push-translations: - requires: - - setup - build-test-deploy: jobs: - setup @@ -208,18 +162,6 @@ workflows: - store_dist: requires: - build - - deploy-npm: - requires: - - lint - - unit - - integration - - build - filters: - branches: - only: - - master - - develop - - /^hotfix\/.*/ - deploy-gh-pages: requires: - lint From 94f268eebaa8c7a670b85e725ded8e953b18429b Mon Sep 17 00:00:00 2001 From: James Mead Date: Tue, 6 Jul 2021 13:23:31 +0100 Subject: [PATCH 03/13] Add deploy key with write access to repo for deploying to GH Pages I followed these instructions [1] to create the key and add it to GitHub and CircleCI. [1]: https://circleci.com/docs/2.0/gh-bb-integration/#creating-a-github-deploy-key --- .circleci/config.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index bc120407fc9..5d349883104 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -134,6 +134,9 @@ jobs: - checkout - *restore_npm_cache - *restore_build_cache + - add_ssh_keys: + fingerprints: + - "27:82:d3:24:48:41:aa:7c:94:40:54:d9:1e:43:d2:9b" - run: | git config --global user.email $(git log --pretty=format:"%ae" -n1) git config --global user.name $(git log --pretty=format:"%an" -n1) From ff77f1881645f76c49d3f1da4a38f7e16058e669 Mon Sep 17 00:00:00 2001 From: James Mead Date: Tue, 6 Jul 2021 14:17:33 +0100 Subject: [PATCH 04/13] Add README section re the RPF customisation in this repo --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 3717731e189..e3564a8647a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,18 @@ # scratch-gui #### Scratch GUI is a set of React components that comprise the interface for creating and running Scratch 3.0 projects +## Raspberry Pi Foundation customisation + +[![CircleCI status of RaspberryPiFoundation/scratch-gui](https://circleci.com/gh/RaspberryPiFoundation/scratch-gui.svg?style=shield&circle-token=d6d268de56c55a3e520e59195047105029345eaf)](https://app.circleci.com/pipelines/github/RaspberryPiFoundation/scratch-gui?branch=code-club-world) + +* This is a fork of [the canonical repo](https://github.com/LLK/scratch-gui.git) to allow us to customise it for the [Code Club World app](https://github.com/RaspberryPiFoundation/codeclubworld). + +* The default branch of the canonical repo is `develop`, but the default branch of this repo is `code-club-world`. This is to make it clear that the latter is where we should be making changes, to make it easier to bring in changes from the upstream repo, and so we can have our own CircleCI configuration to automatically build the app. + +* Commits pushed to the forked repo on GitHub trigger [builds on CircleCI](https://app.circleci.com/pipelines/github/RaspberryPiFoundation/scratch-gui) and a successful build results in the build output being deployed to GitHub Pages for this repo. The deployment makes use of an SSH key with write access to this repo. + +* The deployment adds the build output to the `gh-pages` branch in a sub-directory with the same name as the current branch. Thus the app is available at a URL including that sub-directory, e.g. https://raspberrypifoundation.github.io/scratch-gui/code-club-world/ for the default `code-club-world` branch. + ## Installation This requires you to have Git and Node.js installed. From 97f7c9e6e4adde9ceffb7c618d16d8f6810fb247 Mon Sep 17 00:00:00 2001 From: James Mead Date: Wed, 4 Aug 2021 14:24:55 +0100 Subject: [PATCH 05/13] Export saveProjectToServer & add support for extra HTTP headers I want to be able to send an X-CSRF-Token HTTP header when sending a POST or PUT request to create or update the project. * Exporting saveProjectToServer means that I can set the onUpdateProjectData property to a function which wraps saveProjectToServer. * Adding the optional headers parameter to the saveProjectToServer function means that the wrapping function can pass in extra HTTP headers to be sent in any request. --- src/index.js | 4 +++- src/lib/save-project-to-server.js | 7 +++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/index.js b/src/index.js index 70dda5a90ca..6153742a3c6 100644 --- a/src/index.js +++ b/src/index.js @@ -6,6 +6,7 @@ import {ScratchPaintReducer} from 'scratch-paint'; import {setFullScreen, setPlayer} from './reducers/mode'; import {remixProject} from './reducers/project-state'; import {setAppElement} from 'react-modal'; +import saveProjectToServer from './lib/save-project-to-server'; const guiReducers = { locales: LocalesReducer, @@ -27,5 +28,6 @@ export { localesInitialState, remixProject, setFullScreen, - setPlayer + setPlayer, + saveProjectToServer }; diff --git a/src/lib/save-project-to-server.js b/src/lib/save-project-to-server.js index 2584923e60d..a9c04c369a5 100644 --- a/src/lib/save-project-to-server.js +++ b/src/lib/save-project-to-server.js @@ -12,15 +12,14 @@ import storage from '../lib/storage'; * @property {?boolean} params.isCopy a flag indicating if this save is creating a copy. * @property {?boolean} params.isRemix a flag indicating if this save is creating a remix. * @property {?string} params.title the title of the project. + * @param {object} headers extra HTTP request headers. * @return {Promise} A promise that resolves when the network request resolves. */ -export default function (projectId, vmState, params) { +export default function (projectId, vmState, params, headers) { const opts = { body: vmState, // If we set json:true then the body is double-stringified, so don't - headers: { - 'Content-Type': 'application/json' - }, + headers: Object.assign({'Content-Type': 'application/json'}, headers), withCredentials: true }; const creatingProject = projectId === null || typeof projectId === 'undefined'; From 5a82c84fe62f91a5484e786ac089224f271a9448 Mon Sep 17 00:00:00 2001 From: James Mead Date: Thu, 5 Aug 2021 15:40:20 +0100 Subject: [PATCH 06/13] Publish scoped package on successful builds This reinstates the deploy-npm CircleCI job and tweaks it slightly: * Scope the package name by organisation. This ties the package to the RPF organisation rather than just to my user and means that, for example, any member of the organisation can publish the package. * Only publish package on successful builds of the code-club-world branch. * Use organisation-specific release version and git tag to avoid confusion with versions in the canonical package and tags in upstream repo. * Always publish using "latest" npm tag; not "hotfix" or "stable". * Add `--access public` option to `npm publish` command, because scoped packages only allow "restricted" access by default. * I've added the access token from my npmjs.org account as the NPM_TOKEN env var in the CircleCI project settings. * Add ssh key fingerprint to allow `git push`. --- .circleci/config.yml | 31 +++++++++++++++++++++++++++++++ package-lock.json | 2 +- package.json | 2 +- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5d349883104..fa11f3cbc0a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -127,6 +127,27 @@ jobs: - store_test_results: path: test-results + deploy-npm: + <<: *defaults + environment: + NODE_OPTIONS: --max-old-space-size=4000 + steps: + - *restore_git_cache + - *restore_dist_cache + - checkout + - run: | + echo export RELEASE_VERSION="0.1.0-raspberrypifoundation.$(date +'%Y%m%d%H%M%S')" >> $BASH_ENV + echo export NPM_TAG=latest >> $BASH_ENV + - run: npm version --no-git-tag-version $RELEASE_VERSION + - run: | + npm set //registry.npmjs.org/:_authToken=$NPM_TOKEN + npm publish --access public --tag $NPM_TAG + - add_ssh_keys: + fingerprints: + - "27:82:d3:24:48:41:aa:7c:94:40:54:d9:1e:43:d2:9b" + - run: git tag $RELEASE_VERSION + - run: git push $CIRCLE_REPOSITORY_URL $RELEASE_VERSION + deploy-gh-pages: <<: *defaults steps: @@ -165,6 +186,16 @@ workflows: - store_dist: requires: - build + - deploy-npm: + requires: + - lint + - unit + - integration + - build + filters: + branches: + only: + - code-club-world - deploy-gh-pages: requires: - lint diff --git a/package-lock.json b/package-lock.json index 4fb45d7a120..23e03d9977c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "scratch-gui", + "name": "@raspberrypifoundation/scratch-gui", "version": "0.1.0", "lockfileVersion": 1, "requires": true, diff --git a/package.json b/package.json index 5c9217b0667..a7f6a4ab909 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "scratch-gui", + "name": "@raspberrypifoundation/scratch-gui", "version": "0.1.0", "description": "GraphicaL User Interface for creating and running Scratch 3.0 projects", "main": "./dist/scratch-gui.js", From 7cef984c88446b95fc7ef419d2f215212176af96 Mon Sep 17 00:00:00 2001 From: James Mead Date: Thu, 5 Aug 2021 16:26:54 +0100 Subject: [PATCH 07/13] Change homepage & repo metadata for forked package These are used by npmjs.org to display links on the package page. Since this is a public package I think it's sensible to point at our fork of the canonical repo. --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index a7f6a4ab909..5356db91e05 100644 --- a/package.json +++ b/package.json @@ -20,10 +20,10 @@ }, "author": "Massachusetts Institute of Technology", "license": "BSD-3-Clause", - "homepage": "https://github.com/LLK/scratch-gui#readme", + "homepage": "https://github.com/RaspberryPiFoundation/scratch-gui#readme", "repository": { "type": "git", - "url": "git+ssh://git@github.com/LLK/scratch-gui.git" + "url": "git+ssh://git@github.com/RaspberryPiFoundation/scratch-gui.git" }, "dependencies": { "arraybuffer-loader": "^1.0.6", From 2bb6725c26d31e52ba62f989a17b02cb6b1ca641 Mon Sep 17 00:00:00 2001 From: James Mead Date: Thu, 5 Aug 2021 16:40:09 +0100 Subject: [PATCH 08/13] Update README to explain automatic package publishing from CircleCI --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e3564a8647a..9f592c652d7 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,12 @@ * The default branch of the canonical repo is `develop`, but the default branch of this repo is `code-club-world`. This is to make it clear that the latter is where we should be making changes, to make it easier to bring in changes from the upstream repo, and so we can have our own CircleCI configuration to automatically build the app. -* Commits pushed to the forked repo on GitHub trigger [builds on CircleCI](https://app.circleci.com/pipelines/github/RaspberryPiFoundation/scratch-gui) and a successful build results in the build output being deployed to GitHub Pages for this repo. The deployment makes use of an SSH key with write access to this repo. +* Commits pushed to the forked repo on GitHub trigger [builds on CircleCI](https://app.circleci.com/pipelines/github/RaspberryPiFoundation/scratch-gui) and a successful build results in the build output being deployed to GitHub Pages for this repo and a version of the package being published to [the npm registry](https://www.npmjs.com/). The deployment makes use of an SSH key with write access to this repo. * The deployment adds the build output to the `gh-pages` branch in a sub-directory with the same name as the current branch. Thus the app is available at a URL including that sub-directory, e.g. https://raspberrypifoundation.github.io/scratch-gui/code-club-world/ for the default `code-club-world` branch. +* The deployment publishes an organisation-scoped version of the package: [`@raspberrypifoundation/scratch-gui`](https://www.npmjs.com/package/@raspberrypifoundation/scratch-gui). The publishing of the package makes use of an access token set as an environment variable (`NPM_TOKEN`) in the CircleCI project settings. The git repo is also tagged with the release version. + ## Installation This requires you to have Git and Node.js installed. From fa974ece63d0782cb4e94b28f6e4c11b790436e5 Mon Sep 17 00:00:00 2001 From: Chris Lowis Date: Mon, 9 Aug 2021 09:28:30 +0100 Subject: [PATCH 09/13] Fix prop type validation warning in SpriteSelectorItem In ./src/containers/costume-tab.jsx:271 the SpriteSelctorItem `dragPayload` prop is set to be an object. To supress the prop type warning, I've added `propTypes.object` to the array of allowed types. --- src/containers/sprite-selector-item.jsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/containers/sprite-selector-item.jsx b/src/containers/sprite-selector-item.jsx index f946cf83f1d..1267e19d33d 100644 --- a/src/containers/sprite-selector-item.jsx +++ b/src/containers/sprite-selector-item.jsx @@ -151,7 +151,11 @@ SpriteSelectorItem.propTypes = { asset: PropTypes.instanceOf(storage.Asset), costumeURL: PropTypes.string, dispatchSetHoveredSprite: PropTypes.func.isRequired, - dragPayload: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + dragPayload: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.number, + PropTypes.object + ]), dragType: PropTypes.string, dragging: PropTypes.bool, id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), From bba18ce3c370b03cc44a8dcbcd451b10bd0643f5 Mon Sep 17 00:00:00 2001 From: Chris Lowis Date: Tue, 10 Aug 2021 09:53:13 +0100 Subject: [PATCH 10/13] Fix proptype validation warning in SpriteList We've seen a PropType warning for this prop in development. It seems that when the SpriteList component is used to manage the costumes in the left hand side of the Costumes tab, numeric identifiers are used for `sprite`. When the SpriteList is used in the sprite selection area under the stage, strings are used. There's probably a way of fixing this at source, but for now being a bit more permissive with the validation removes the warning. As far as I can tell from reading the source, we use this id for comparison with the `===` operator, so I think numbers or strings are functionally equivalent. --- src/components/sprite-selector/sprite-list.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/sprite-selector/sprite-list.jsx b/src/components/sprite-selector/sprite-list.jsx index 3d191029345..3ced6902a16 100644 --- a/src/components/sprite-selector/sprite-list.jsx +++ b/src/components/sprite-selector/sprite-list.jsx @@ -111,7 +111,7 @@ SpriteList.propTypes = { hoveredTarget: PropTypes.shape({ hoveredSprite: PropTypes.string, receivedBlocks: PropTypes.bool, - sprite: PropTypes.string + sprite: PropTypes.oneOfType([PropTypes.number, PropTypes.string]) }), items: PropTypes.arrayOf(PropTypes.shape({ costume: PropTypes.shape({ From 3baff164c278615bd84f523a2e6e1955b7cfc233 Mon Sep 17 00:00:00 2001 From: Magdalena Jadach Date: Fri, 19 May 2023 11:48:54 +0100 Subject: [PATCH 11/13] Bump color shade --- src/css/colors.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/css/colors.css b/src/css/colors.css index 6f38510e254..fb71c5d5712 100644 --- a/src/css/colors.css +++ b/src/css/colors.css @@ -14,7 +14,7 @@ $ui-black-transparent: hsla(0, 0%, 0%, 0.15); /* 15% transparent version of blac $text-primary: hsla(225, 15%, 40%, 1); /* #575E75 */ $text-primary-transparent: hsla(225, 15%, 40%, 0.75); -$motion-primary: hsla(215, 100%, 65%, 1); /* #4C97FF */ +$motion-primary: hsla(215, 60%, 50%, 1); /* #3373CC */ $motion-tertiary: hsla(215, 60%, 50%, 1); /* #3373CC */ $motion-transparent: hsla(215, 100%, 65%, 0.35); /* 35% transparent version of motion-primary */ $motion-light-transparent: hsla(215, 100%, 65%, 0.15); /* 15% transparent version of motion-primary */ From 5e2d980ebea79fff211489750ced83042ede7c01 Mon Sep 17 00:00:00 2001 From: Magdalena Jadach Date: Tue, 30 May 2023 15:38:47 +0100 Subject: [PATCH 12/13] Fix nav images alt --- src/components/gui/gui.jsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/gui/gui.jsx b/src/components/gui/gui.jsx index 03180042826..399add873af 100644 --- a/src/components/gui/gui.jsx +++ b/src/components/gui/gui.jsx @@ -259,6 +259,7 @@ const GUIComponent = props => { {"Code { {"Costumes {targetIsStage ? ( { {"Sounds { className={styles.extensionButtonIcon} draggable={false} src={addExtensionIcon} + alt={"Add extension icon"} /> From c5b8727267514fd325984ee9ffcf09245377969f Mon Sep 17 00:00:00 2001 From: Scott Date: Tue, 6 Jun 2023 08:11:28 +0100 Subject: [PATCH 13/13] fix(gui.jsx): linting --- src/components/gui/gui.jsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/gui/gui.jsx b/src/components/gui/gui.jsx index 399add873af..a4b50860867 100644 --- a/src/components/gui/gui.jsx +++ b/src/components/gui/gui.jsx @@ -259,7 +259,7 @@ const GUIComponent = props => { {"Code { {"Costumes {targetIsStage ? ( { {"Sounds { className={styles.extensionButtonIcon} draggable={false} src={addExtensionIcon} - alt={"Add extension icon"} + alt={'Add extension icon'} />