From 4749bd1bbd9d794f30e13b05d43be623ebdfad13 Mon Sep 17 00:00:00 2001 From: Colby Gutierrez-Kraybill Date: Tue, 21 Aug 2018 13:09:38 -0400 Subject: [PATCH 01/60] Add docker-up and docker-down rules to Makefile. Now depends on a npm module 'scratch-docker' which brings a network configuration script that handles creating a named docker network that all other scratch repos that have docker configurations depend on --- Makefile | 14 ++++++++++++++ docker-compose.yml | 9 ++++----- package.json | 1 + 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 21100b6f4..f68ed91c9 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,25 @@ ESLINT=./node_modules/.bin/eslint NODE= NODE_OPTIONS=--max_old_space_size=8000 node SASSLINT=./node_modules/.bin/sass-lint -v +SCRATCH_DOCKER_CONFIG=./node_modules/.bin/docker_config.sh S3CMD=s3cmd sync -P --delete-removed --add-header=Cache-Control:no-cache,public,max-age=3600 TAP=./node_modules/.bin/tap WATCH= NODE_OPTIONS=--max_old_space_size=8000 ./node_modules/.bin/watch WEBPACK= NODE_OPTIONS=--max_old_space_size=8000 ./node_modules/.bin/webpack + +# ------------------------------------ + +$(SCRATCH_DOCKER_CONFIG): + npm install scratch-docker + +docker-up: $(SCRATCH_DOCKER_CONFIG) + $(SCRATCH_DOCKER_CONFIG) network create + docker-compose up + +docker-down: + docker-compose down + # ------------------------------------ build: diff --git a/docker-compose.yml b/docker-compose.yml index e7919d96f..66e728695 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,8 +4,9 @@ volumes: runtime_data: networks: - scratch-api_scratch_network: - external: true + default: + external: + name: scratchapi_scratch_network services: app: @@ -13,7 +14,7 @@ services: hostname: scratch-www-app environment: - API_HOST=http://localhost:8491 - - FALLBACK=http://localhost:8080 + - FALLBACK=http://scratchr2-app:8080 - USE_DOCKER_WATCHOPTIONS=true build: context: ./ @@ -35,5 +36,3 @@ services: - runtime_data:/runtime ports: - "8333:8333" - networks: - - scratch-api_scratch_network diff --git a/package.json b/package.json index e8bbee511..76d1424c4 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "lodash.defaults": "4.0.1", "newrelic": "1.25.4", "raven": "0.10.0", + "scratch-docker": "^1.0.2", "scratch-parser": "^4.2.0", "scratch-storage": "^0.5.1" }, From 1ff394f9b2ed5524bc1b9cffc89155ba4a23467d Mon Sep 17 00:00:00 2001 From: Italy Date: Tue, 21 Aug 2018 15:39:59 -0400 Subject: [PATCH 02/60] adding simple alt attributes to imgs on ev3 landing page --- src/views/ev3/ev3.jsx | 20 ++++++++++++++++---- src/views/ev3/l10n.json | 9 ++++++++- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/views/ev3/ev3.jsx b/src/views/ev3/ev3.jsx index 27e316031..de25bd133 100644 --- a/src/views/ev3/ev3.jsx +++ b/src/views/ev3/ev3.jsx @@ -31,7 +31,10 @@ class EV3 extends ExtensionLanding { render () { return (
- +

LEGO MINDSTORMS EV3

- + {this.props.intl.formatMessage({id:

- + {this.props.intl.formatMessage({id:

@@ -170,7 +179,10 @@ class EV3 extends ExtensionLanding { />
- + {this.props.intl.formatMessage({id:
Date: Tue, 21 Aug 2018 16:07:27 -0400 Subject: [PATCH 03/60] added alt attributes to img tags in starter projects component and when using this component on ev3 page --- src/components/extension-landing/project-card.jsx | 6 +++++- src/views/ev3/ev3.jsx | 3 +++ src/views/ev3/l10n.json | 5 ++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/components/extension-landing/project-card.jsx b/src/components/extension-landing/project-card.jsx index 44606f7b8..09a4ce182 100644 --- a/src/components/extension-landing/project-card.jsx +++ b/src/components/extension-landing/project-card.jsx @@ -8,7 +8,10 @@ const ProjectCard = props => ( href={props.cardUrl} >
- + {props.imageAlt}

{props.title}

@@ -20,6 +23,7 @@ const ProjectCard = props => ( ProjectCard.propTypes = { cardUrl: PropTypes.string, description: PropTypes.string, + imageAlt: PropTypes.string, imageSrc: PropTypes.string, title: PropTypes.string }; diff --git a/src/views/ev3/ev3.jsx b/src/views/ev3/ev3.jsx index de25bd133..3e395bdc2 100644 --- a/src/views/ev3/ev3.jsx +++ b/src/views/ev3/ev3.jsx @@ -210,18 +210,21 @@ class EV3 extends ExtensionLanding { diff --git a/src/views/ev3/l10n.json b/src/views/ev3/l10n.json index b96d679ee..244133609 100644 --- a/src/views/ev3/l10n.json +++ b/src/views/ev3/l10n.json @@ -41,5 +41,8 @@ "ev3.imgAltAcceptPasscode": "Use the center button of your EV3 to accept the passcode.", "ev3.imgAltWaitForWindows": "Windows notifies you when EV3 is ready.", "ev3.imgAltEnterPasscodeMac": "Enter the passcode into the connection request window opening on your Mac.", - "ev3.imgAltPlugInMotor": "Port A is not to be confused with Port 4 on the other side of the EV3." + "ev3.imgAltPlugInMotor": "Port A is not to be confused with Port 4 on the other side of the EV3.", + "ev3.imgAltWaveHello": "A fairy", + "ev3.imgAltDistanceInstrument": "A guitar on stage", + "ev3.imgAltSpaceTacos": "A cat and a taco in space" } From 25234d7e276613aa4e7642acb9aaf0cf0148791c Mon Sep 17 00:00:00 2001 From: Linda Date: Tue, 21 Aug 2018 16:33:50 -0400 Subject: [PATCH 04/60] add conditional alt attributes to ev3 landing page installation step --- src/views/ev3/ev3.jsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/views/ev3/ev3.jsx b/src/views/ev3/ev3.jsx index 3e395bdc2..3939b6b3e 100644 --- a/src/views/ev3/ev3.jsx +++ b/src/views/ev3/ev3.jsx @@ -141,6 +141,11 @@ class EV3 extends ExtensionLanding {
{this.props.intl.formatMessage({id: Date: Tue, 21 Aug 2018 16:40:49 -0400 Subject: [PATCH 05/60] making the conditional translation more elegant --- src/views/ev3/ev3.jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/views/ev3/ev3.jsx b/src/views/ev3/ev3.jsx index 3939b6b3e..a29d2e433 100644 --- a/src/views/ev3/ev3.jsx +++ b/src/views/ev3/ev3.jsx @@ -141,10 +141,10 @@ class EV3 extends ExtensionLanding {
{this.props.intl.formatMessage({id: Date: Wed, 22 Aug 2018 10:21:28 -0400 Subject: [PATCH 06/60] add alt tags to remaining images and correct some --- .../install-scratch-link.jsx | 6 ++- src/views/ev3/ev3.jsx | 40 +++++++++++++++---- src/views/ev3/l10n.json | 6 +-- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/components/extension-landing/install-scratch-link.jsx b/src/components/extension-landing/install-scratch-link.jsx index 07e0fddd0..28ac6a5a0 100644 --- a/src/components/extension-landing/install-scratch-link.jsx +++ b/src/components/extension-landing/install-scratch-link.jsx @@ -35,7 +35,10 @@ const InstallScratchLink = ({ : } - + @@ -50,6 +53,7 @@ const InstallScratchLink = ({
-

LEGO MINDSTORMS EV3

+

LEGO MINDSTORMS EV3

- + Windows 10+ - + macOS 10.13+ @@ -66,7 +75,10 @@ class EV3 extends ExtensionLanding { Bluetooth - + Scratch Link @@ -85,13 +97,19 @@ class EV3 extends ExtensionLanding {
- +

- +

- + {this.props.intl.formatMessage({id:

@@ -205,7 +226,10 @@ class EV3 extends ExtensionLanding { />
- +
diff --git a/src/views/ev3/l10n.json b/src/views/ev3/l10n.json index 244133609..f77cc6fa6 100644 --- a/src/views/ev3/l10n.json +++ b/src/views/ev3/l10n.json @@ -42,7 +42,7 @@ "ev3.imgAltWaitForWindows": "Windows notifies you when EV3 is ready.", "ev3.imgAltEnterPasscodeMac": "Enter the passcode into the connection request window opening on your Mac.", "ev3.imgAltPlugInMotor": "Port A is not to be confused with Port 4 on the other side of the EV3.", - "ev3.imgAltWaveHello": "A fairy", - "ev3.imgAltDistanceInstrument": "A guitar on stage", - "ev3.imgAltSpaceTacos": "A cat and a taco in space" + "ev3.imgAltWaveHello": "Example of a Scratch project with a waving fairy.", + "ev3.imgAltDistanceInstrument": "Example of a Scratch project with a guitar.", + "ev3.imgAltSpaceTacos": "Example of a Scratch project with Scratch Cat and a taco in space." } From 9a91fa9b0aa021c1ee6091a1d9bd7d5ae2d8fd61 Mon Sep 17 00:00:00 2001 From: Linda Date: Wed, 22 Aug 2018 10:45:19 -0400 Subject: [PATCH 07/60] h2 in header is now h1, including overwritten styles --- .../extension-landing/extension-landing.scss | 16 ++++++++++------ src/views/ev3/ev3.jsx | 4 ++-- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/components/extension-landing/extension-landing.scss b/src/components/extension-landing/extension-landing.scss index e9555bdba..85b66c1ee 100644 --- a/src/components/extension-landing/extension-landing.scss +++ b/src/components/extension-landing/extension-landing.scss @@ -10,7 +10,11 @@ padding: 4rem 0; } - h2 { + h1 { + font-size: 2rem; + } + + h1, h2 { margin-bottom: 1rem; } @@ -84,15 +88,15 @@ margin-bottom: 5rem; align-items: flex-start; - h2 { + h1, h2 { display: flex; margin-bottom: 2rem; color: $ui-white; - } - h2 img { - padding-right: .5rem; - max-height: 100%; + img { + padding-right: .5rem; + max-height: 100%; + } } span { diff --git a/src/views/ev3/ev3.jsx b/src/views/ev3/ev3.jsx index b6b154fde..63ed40e01 100644 --- a/src/views/ev3/ev3.jsx +++ b/src/views/ev3/ev3.jsx @@ -36,10 +36,10 @@ class EV3 extends ExtensionLanding { imageSrc="/images/ev3/ev3-illustration.png" > -

LEGO MINDSTORMS EV3

+ />LEGO MINDSTORMS EV3 Date: Wed, 22 Aug 2018 13:05:49 -0400 Subject: [PATCH 08/60] add language tag --- src/init.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/init.js b/src/init.js index 883aca0ad..0954c5315 100644 --- a/src/init.js +++ b/src/init.js @@ -35,6 +35,7 @@ const Raven = require('raven-js'); }; window._locale = updateLocale(); + document.documentElement.lang = window._locale; })(); /** From 253d6ac279c24ea051c62756e481f58dcd58c9cb Mon Sep 17 00:00:00 2001 From: Linda Date: Wed, 22 Aug 2018 13:32:23 -0400 Subject: [PATCH 09/60] style fix --- src/components/navigation/www/navigation.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/navigation/www/navigation.jsx b/src/components/navigation/www/navigation.jsx index fddfbafaf..1a0fedb9f 100644 --- a/src/components/navigation/www/navigation.jsx +++ b/src/components/navigation/www/navigation.jsx @@ -249,7 +249,7 @@ class Navigation extends React.Component { 'message-count': true, 'show': this.props.unreadMessageCount > 0 })} - >{this.props.unreadMessageCount} + >{this.props.unreadMessageCount} , From a7c279fab5d51c8866ea997f0e181bd89418ad60 Mon Sep 17 00:00:00 2001 From: Linda Date: Wed, 22 Aug 2018 15:05:21 -0400 Subject: [PATCH 10/60] cut of studio name on studio adding dialog using css and not using the library for that anymore, also displays full title as a title of the div --- src/components/modal/addtostudio/modal.scss | 5 ++++- src/components/modal/addtostudio/studio-button.jsx | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/modal/addtostudio/modal.scss b/src/components/modal/addtostudio/modal.scss index 08b4c1abc..38267fe90 100644 --- a/src/components/modal/addtostudio/modal.scss +++ b/src/components/modal/addtostudio/modal.scss @@ -112,11 +112,14 @@ */ margin: .575rem 2.18375rem .175rem .6875rem; width: 13.3125rem; - height: 1rem; /* diff from spec, in case we ever do valign to middle */ + height: 1.25rem; /* diff from spec, in case we ever do valign to middle; changed to match line-height because else with overflow hidden it cuts off some letters */ line-height: 1.25rem; font-family: "Helvetica Neue"; font-size: .875rem; font-weight: regular; + overflow: hidden; + text-overflow:ellipsis; + white-space: nowrap; } .studio-selector-button-selected { diff --git a/src/components/modal/addtostudio/studio-button.jsx b/src/components/modal/addtostudio/studio-button.jsx index 137c4cc8a..45e0ebf99 100644 --- a/src/components/modal/addtostudio/studio-button.jsx +++ b/src/components/modal/addtostudio/studio-button.jsx @@ -44,8 +44,9 @@ const StudioButton = ({ {'studio-selector-button-text-selected': includesProject || hasRequestOutstanding}, {'studio-selector-button-text-unselected': !includesProject && !hasRequestOutstanding} )} + title={title} > - {truncateAtWordBoundary(title, 25)} + {title}
Date: Wed, 22 Aug 2018 15:10:19 -0400 Subject: [PATCH 11/60] remove now obsolete truncate library --- package.json | 1 - src/components/modal/addtostudio/studio-button.jsx | 1 - src/lib/truncate.js | 9 --------- 3 files changed, 11 deletions(-) delete mode 100644 src/lib/truncate.js diff --git a/package.json b/package.json index e8bbee511..6b1315452 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,6 @@ "lodash.merge": "3.3.2", "lodash.omit": "3.1.0", "lodash.range": "3.0.1", - "lodash.truncate": "4.4.2", "minilog": "2.0.8", "node-dir": "0.1.16", "node-sass": "4.6.1", diff --git a/src/components/modal/addtostudio/studio-button.jsx b/src/components/modal/addtostudio/studio-button.jsx index 45e0ebf99..3a19ac5de 100644 --- a/src/components/modal/addtostudio/studio-button.jsx +++ b/src/components/modal/addtostudio/studio-button.jsx @@ -1,4 +1,3 @@ -const truncateAtWordBoundary = require('../../../lib/truncate').truncateAtWordBoundary; const PropTypes = require('prop-types'); const React = require('react'); const classNames = require('classnames'); diff --git a/src/lib/truncate.js b/src/lib/truncate.js deleted file mode 100644 index 36a7477f7..000000000 --- a/src/lib/truncate.js +++ /dev/null @@ -1,9 +0,0 @@ -const lodashTruncate = require('lodash.truncate'); - -/* -* Function that applies regex for word boundaries, replaces removed string -* with indication of ellipsis (...) -*/ -module.exports.truncateAtWordBoundary = (str, length) => ( - lodashTruncate(str, {length: length, separator: /[.,:;]*\s+/}) -); From 56d9ac2af9af80a4227ea5ea49f75dc9e9d340fa Mon Sep 17 00:00:00 2001 From: Linda Date: Wed, 22 Aug 2018 16:48:07 -0400 Subject: [PATCH 12/60] resolve travis errors caused by wrong ordering of css stuff --- src/components/modal/addtostudio/modal.scss | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/modal/addtostudio/modal.scss b/src/components/modal/addtostudio/modal.scss index 38267fe90..3719b1e57 100644 --- a/src/components/modal/addtostudio/modal.scss +++ b/src/components/modal/addtostudio/modal.scss @@ -113,13 +113,13 @@ margin: .575rem 2.18375rem .175rem .6875rem; width: 13.3125rem; height: 1.25rem; /* diff from spec, in case we ever do valign to middle; changed to match line-height because else with overflow hidden it cuts off some letters */ + overflow: hidden; + text-overflow: ellipsis; line-height: 1.25rem; + white-space: nowrap; font-family: "Helvetica Neue"; font-size: .875rem; font-weight: regular; - overflow: hidden; - text-overflow:ellipsis; - white-space: nowrap; } .studio-selector-button-selected { From f51f6801e6e1873a00ff57156913ea6908ad2c0b Mon Sep 17 00:00:00 2001 From: Eric Rosenbaum Date: Thu, 23 Aug 2018 10:03:02 -0400 Subject: [PATCH 13/60] Add wedo troubleshooting item about updating scratch link --- src/views/wedo2/l10n.json | 2 ++ src/views/wedo2/wedo2.jsx | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/src/views/wedo2/l10n.json b/src/views/wedo2/l10n.json index ca3b8b5c7..414b158a7 100644 --- a/src/views/wedo2/l10n.json +++ b/src/views/wedo2/l10n.json @@ -21,6 +21,8 @@ "wedo2.closeScratchCopiesText": "Only one copy of Scratch can connect with the WeDo 2.0 at a time. If you have Scratch open in other browser tabs, close it and try again.", "wedo2.otherComputerConnectedTitle": "Make sure no other computer is connected to your WeDo 2.0", "wedo2.otherComputerConnectedText": "Only one computer can be connected to an WeDo 2.0 at a time. If you have another computer connected to your WeDo 2.0, disconnect the WeDo 2.0 or close Scratch on that computer and try again.", + "wedo2.updateLinkTitle": "Update Scratch Link", + "wedo2.updateLinkText": "Make sure you have installed the latest version of Scratch Link.", "wedo2.legacyInfoTitle": "Using Scratch 2.0?", "wedo2.legacyInfoText": "Visit our page about {wedoLegacyLink}.", "wedo2.legacyLinkText": "using LEGO WeDo with Scratch 2.0" diff --git a/src/views/wedo2/wedo2.jsx b/src/views/wedo2/wedo2.jsx index 3b583e2f3..855cf0a81 100644 --- a/src/views/wedo2/wedo2.jsx +++ b/src/views/wedo2/wedo2.jsx @@ -180,6 +180,10 @@ class Wedo2 extends ExtensionLanding {

+

+

+ +

Date: Thu, 23 Aug 2018 10:38:49 -0400 Subject: [PATCH 14/60] added alt tags to wedo page --- src/l10n.json | 2 ++ src/views/ev3/ev3.jsx | 2 +- src/views/wedo2/l10n.json | 5 ++++- src/views/wedo2/wedo2.jsx | 45 ++++++++++++++++++++++++++++++++------- 4 files changed, 44 insertions(+), 10 deletions(-) diff --git a/src/l10n.json b/src/l10n.json index a399ad6b2..13e327d37 100644 --- a/src/l10n.json +++ b/src/l10n.json @@ -106,6 +106,8 @@ "navigation.signOut": "Sign out", "extensionHeader.requirements": "Requirements", + "extensionInstallation.addExtension": "In the editor, click on the \"Add Extensions\" button on the lower left.", + "oschooser.choose": "Choose your OS:", diff --git a/src/views/ev3/ev3.jsx b/src/views/ev3/ev3.jsx index 8cc13d7a4..5f6656e22 100644 --- a/src/views/ev3/ev3.jsx +++ b/src/views/ev3/ev3.jsx @@ -132,7 +132,7 @@ class EV3 extends ExtensionLanding {

{this.props.intl.formatMessage({id: diff --git a/src/views/wedo2/l10n.json b/src/views/wedo2/l10n.json index ca3b8b5c7..6697cd543 100644 --- a/src/views/wedo2/l10n.json +++ b/src/views/wedo2/l10n.json @@ -23,5 +23,8 @@ "wedo2.otherComputerConnectedText": "Only one computer can be connected to an WeDo 2.0 at a time. If you have another computer connected to your WeDo 2.0, disconnect the WeDo 2.0 or close Scratch on that computer and try again.", "wedo2.legacyInfoTitle": "Using Scratch 2.0?", "wedo2.legacyInfoText": "Visit our page about {wedoLegacyLink}.", - "wedo2.legacyLinkText": "using LEGO WeDo with Scratch 2.0" + "wedo2.legacyLinkText": "using LEGO WeDo with Scratch 2.0", + "wedo2.imgAltStarter1": "An example project with a dog and a taco.", + "wedo2.imgAltStarter2": "An example project with a toad playing instruments in space.", + "wedo2.imgAltStarter3": "An example project with dinosaurs." } diff --git a/src/views/wedo2/wedo2.jsx b/src/views/wedo2/wedo2.jsx index 3b583e2f3..3a9cd146c 100644 --- a/src/views/wedo2/wedo2.jsx +++ b/src/views/wedo2/wedo2.jsx @@ -28,9 +28,15 @@ class Wedo2 extends ExtensionLanding { render () { return (
- + -

LEGO WeDo 2.0

+

LEGO WeDo 2.0

- + Windows 10+ - + macOS 10.13+ - + Bluetooth - + Scratch Link @@ -80,6 +98,7 @@ class Wedo2 extends ExtensionLanding {
@@ -104,6 +123,7 @@ class Wedo2 extends ExtensionLanding {
{this.props.intl.formatMessage({id: @@ -125,7 +145,10 @@ class Wedo2 extends ExtensionLanding {
- +
- +
@@ -153,18 +179,21 @@ class Wedo2 extends ExtensionLanding { From b3b0843b753caa84ee62b82eaed8066220474a48 Mon Sep 17 00:00:00 2001 From: Linda Date: Thu, 23 Aug 2018 11:05:38 -0400 Subject: [PATCH 15/60] some improvements and added alt attributes for microbit --- src/views/ev3/ev3.jsx | 2 +- src/views/ev3/l10n.json | 2 +- src/views/microbit/l10n.json | 8 ++++- src/views/microbit/microbit.jsx | 61 +++++++++++++++++++++++++++------ src/views/wedo2/l10n.json | 1 + src/views/wedo2/wedo2.jsx | 2 +- 6 files changed, 61 insertions(+), 15 deletions(-) diff --git a/src/views/ev3/ev3.jsx b/src/views/ev3/ev3.jsx index 5f6656e22..476f76f81 100644 --- a/src/views/ev3/ev3.jsx +++ b/src/views/ev3/ev3.jsx @@ -32,7 +32,7 @@ class EV3 extends ExtensionLanding { return (
diff --git a/src/views/ev3/l10n.json b/src/views/ev3/l10n.json index 6c49ddced..d1a79b471 100644 --- a/src/views/ev3/l10n.json +++ b/src/views/ev3/l10n.json @@ -35,7 +35,7 @@ "ev3.updateFirmwareTitle": "Try updating your EV3 firmware", "ev3.updateFirmwareText": "We recommend updating to EV3 firmware version 1.10E or above. See {firmwareUpdateLink}.", "ev3.firmwareUpdateText": "firmware update instructions from LEGO", - "ev3.imgAltEv3illustration": "Illustration of an EV3 Computer featuring some examples of interacting with an EV3.", + "ev3.imgAltEv3Illustration": "Illustration of an EV3 Computer featuring some examples of interacting with an EV3.", "ev3.imgAltAddExtension": "In the editor, click on the \"Add Extensions\" button on the lower left.", "ev3.imgAltAcceptConnection": "Use the buttons of your EV3 to accept the connection.", "ev3.imgAltAcceptPasscode": "Use the center button of your EV3 to accept the passcode.", diff --git a/src/views/microbit/l10n.json b/src/views/microbit/l10n.json index 84dd874b2..871ef7016 100644 --- a/src/views/microbit/l10n.json +++ b/src/views/microbit/l10n.json @@ -28,5 +28,11 @@ "microbit.otherComputerConnectedTitle": "Make sure no other computer is connected to your micro:bit", "microbit.otherComputerConnectedText": "Only one computer can be connected to an micro:bit at a time. If you have another computer connected to your micro:bit, disconnect the micro:bit or close Scratch on that computer and try again.", "microbit.resetButtonTitle": "Make sure you aren’t hitting the “reset” button", - "microbit.resetButtonText": "Sometimes while using the micro:bit you can accidentally press the “reset” button on the back in-between the USB and power ports. Make sure you keep your fingers (and toes) away from it while using Scratch!" + "microbit.resetButtonText": "Sometimes while using the micro:bit you can accidentally press the “reset” button on the back in-between the USB and power ports. Make sure you keep your fingers (and toes) away from it while using Scratch!", + "microbit.imgAltMicrobitIllustration": "Illustration of the micro:bit circuit board.", + "microbit.imgAltDragDropHex": "Drag and drop the HEX file from the folder you downloaded it to to the micro:bit.", + "microbit.imgAltDisplayH": "A micro:bit displaying an H.", + "microbit.imgAltHeartBeat" : "An example project with a heart.", + "microbit.imgAltTiltGuitar": "An example project with a guitar.", + "microbit.imgAltOceanAdventure": "An example project with a clown fish and a saxophone under water." } diff --git a/src/views/microbit/microbit.jsx b/src/views/microbit/microbit.jsx index 2a1b39280..1e04bbf09 100644 --- a/src/views/microbit/microbit.jsx +++ b/src/views/microbit/microbit.jsx @@ -31,9 +31,15 @@ class MicroBit extends ExtensionLanding { render () { return (
- + -

micro:bit

+

micro:bit

- + Windows 10+ - + macOS 10.13+ - + Bluetooth 4.0 - + Scratch Link @@ -82,7 +100,10 @@ class MicroBit extends ExtensionLanding {
- +

@@ -90,7 +111,10 @@ class MicroBit extends ExtensionLanding {

- +
{this.props.intl.formatMessage({id:
- +

@@ -151,6 +180,7 @@ class MicroBit extends ExtensionLanding {
{this.props.intl.formatMessage({id: @@ -181,7 +211,10 @@ class MicroBit extends ExtensionLanding { />
- +
- + {this.props.intl.formatMessage({id:
@@ -209,18 +245,21 @@ class MicroBit extends ExtensionLanding { diff --git a/src/views/wedo2/l10n.json b/src/views/wedo2/l10n.json index 6697cd543..5736298fc 100644 --- a/src/views/wedo2/l10n.json +++ b/src/views/wedo2/l10n.json @@ -24,6 +24,7 @@ "wedo2.legacyInfoTitle": "Using Scratch 2.0?", "wedo2.legacyInfoText": "Visit our page about {wedoLegacyLink}.", "wedo2.legacyLinkText": "using LEGO WeDo with Scratch 2.0", + "wedo2.imgAltWeDoIllustration": "An illustration of a WeDo2 featuring a tilt sensor and a motor.", "wedo2.imgAltStarter1": "An example project with a dog and a taco.", "wedo2.imgAltStarter2": "An example project with a toad playing instruments in space.", "wedo2.imgAltStarter3": "An example project with dinosaurs." diff --git a/src/views/wedo2/wedo2.jsx b/src/views/wedo2/wedo2.jsx index 3a9cd146c..8a8eaa93c 100644 --- a/src/views/wedo2/wedo2.jsx +++ b/src/views/wedo2/wedo2.jsx @@ -29,7 +29,7 @@ class Wedo2 extends ExtensionLanding { return (
From f934b9bc7ecb4dd3fb8ae248ff60205fc055b53b Mon Sep 17 00:00:00 2001 From: Linda Date: Thu, 23 Aug 2018 11:18:12 -0400 Subject: [PATCH 16/60] fixed some intendation --- src/components/extension-landing/extension-landing.scss | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/extension-landing/extension-landing.scss b/src/components/extension-landing/extension-landing.scss index eb01f24ff..536c6d736 100644 --- a/src/components/extension-landing/extension-landing.scss +++ b/src/components/extension-landing/extension-landing.scss @@ -11,7 +11,7 @@ } h1 { - font-size: 2rem; + font-size: 2rem; } h1, h2 { @@ -95,8 +95,8 @@ color: $ui-white; img { - padding-right: .5rem; - max-height: 100%; + padding-right: .5rem; + max-height: 100%; } } From 50242a3bb1b69ddeb7b23a787b0fdf31c85298c8 Mon Sep 17 00:00:00 2001 From: Linda Date: Thu, 23 Aug 2018 11:32:18 -0400 Subject: [PATCH 17/60] added pointer cursor style to the buttons that add or remove a project to or from a studio --- src/components/modal/addtostudio/modal.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/modal/addtostudio/modal.scss b/src/components/modal/addtostudio/modal.scss index 08b4c1abc..a1e1e88f5 100644 --- a/src/components/modal/addtostudio/modal.scss +++ b/src/components/modal/addtostudio/modal.scss @@ -96,6 +96,7 @@ margin: .21875rem .21875rem; border-radius: .5rem; background-color: $ui-white; + cursor: pointer; padding: 0; width: 16.1875rem; /* 259px */ height: 2.5rem; From 796ad7b152ef01c90995c77b05b347e1da23ede0 Mon Sep 17 00:00:00 2001 From: Ben Wheeler Date: Sun, 12 Aug 2018 13:09:29 -0400 Subject: [PATCH 18/60] split account nav into its own component --- src/components/navigation/www/accountnav.jsx | 101 +++++++++++++++++++ src/components/navigation/www/navigation.jsx | 79 ++++----------- 2 files changed, 119 insertions(+), 61 deletions(-) create mode 100644 src/components/navigation/www/accountnav.jsx diff --git a/src/components/navigation/www/accountnav.jsx b/src/components/navigation/www/accountnav.jsx new file mode 100644 index 000000000..1f8c8cc9d --- /dev/null +++ b/src/components/navigation/www/accountnav.jsx @@ -0,0 +1,101 @@ +const classNames = require('classnames'); +const FormattedMessage = require('react-intl').FormattedMessage; +const injectIntl = require('react-intl').injectIntl; +const PropTypes = require('prop-types'); +const React = require('react'); + +const Avatar = require('../../avatar/avatar.jsx'); +const Dropdown = require('../../dropdown/dropdown.jsx'); + +require('./navigation.scss'); + +const AccountNav = ({ + classroomId, + isEducator, + isOpen, + isStudent, + profileUrl, + thumbnailUrl, + username, + onClick, + onClickLogout, + onClose +}) => ( + + + + + {username} + + + +
  • + + + +
  • +
  • + + + +
  • + {isEducator ? [ +
  • + + + +
  • + ] : []} + {isStudent ? [ +
  • + + + +
  • + ] : []} +
  • + + + +
  • +
  • + + + +
  • +
    + +); + +AccountNav.propTypes = { + classroomId: PropTypes.string, + isEducator: PropTypes.bool, + isOpen: PropTypes.bool, + isStudent: PropTypes.bool, + onClick: PropTypes.func, + onClickLogout: PropTypes.func, + onClose: PropTypes.func, + profileUrl: PropTypes.string, + thumbnailUrl: PropTypes.string, + username: PropTypes.string +}; + +module.exports = injectIntl(AccountNav); diff --git a/src/components/navigation/www/navigation.jsx b/src/components/navigation/www/navigation.jsx index 1a0fedb9f..78de52873 100644 --- a/src/components/navigation/www/navigation.jsx +++ b/src/components/navigation/www/navigation.jsx @@ -11,7 +11,6 @@ const messageCountActions = require('../../../redux/message-count.js'); const sessionActions = require('../../../redux/session.js'); const api = require('../../../lib/api'); -const Avatar = require('../../avatar/avatar.jsx'); const Button = require('../../forms/button.jsx'); const Dropdown = require('../../dropdown/dropdown.jsx'); const Form = require('../../forms/form.jsx'); @@ -21,6 +20,7 @@ const Login = require('../../login/login.jsx'); const Modal = require('../../modal/base/modal.jsx'); const NavigationBox = require('../base/navigation.jsx'); const Registration = require('../../registration/registration.jsx'); +const AccountNav = require('./accountnav.jsx'); require('./navigation.scss'); @@ -268,66 +268,18 @@ class Navigation extends React.Component { className="link right account-nav" key="account-nav" > - - - - {this.props.session.session.user.username} - - - -
  • - - - -
  • -
  • - - - -
  • - {this.props.permissions.educator ? [ -
  • - - - -
  • - ] : []} - {this.props.permissions.student ? [ -
  • - - - -
  • - ] : []} -
  • - - - -
  • -
  • - - - -
  • -
    + isStudent={this.props.permissions.student} + profileUrl={this.getProfileUrl()} + thumbnailUrl={this.props.session.session.user.thumbnailUrl} + username={this.props.session.session.user.username} + onClick={this.handleAccountNavClick} + onClickLogout={this.handleLogOut} + onClose={this.handleCloseAccountNav} + /> ] : [
  • ({ searchTerm: state.navigation }); -const ConnectedNavigation = connect(mapStateToProps)(Navigation); +const mapDispatchToProps = () => ({}); + +const ConnectedNavigation = connect( + mapStateToProps, + mapDispatchToProps +)(Navigation); module.exports = injectIntl(ConnectedNavigation); From 9db42fe9f422014b7953d462ebc27d2643164b4a Mon Sep 17 00:00:00 2001 From: Linda Date: Thu, 23 Aug 2018 14:24:31 -0400 Subject: [PATCH 19/60] prevented overflowing project title in a nice looking way --- src/views/preview/presentation.jsx | 5 ++++- src/views/preview/preview.scss | 13 ++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/views/preview/presentation.jsx b/src/views/preview/presentation.jsx index bffa0f829..98400fbea 100644 --- a/src/views/preview/presentation.jsx +++ b/src/views/preview/presentation.jsx @@ -99,7 +99,10 @@ const PreviewPresentation = ({ value={projectInfo.title} /> : -
    {projectInfo.title}
    +
    {projectInfo.title}
    {'by '} {projectInfo.author.username} diff --git a/src/views/preview/preview.scss b/src/views/preview/preview.scss index 8aefd8ead..9e6c98d1c 100644 --- a/src/views/preview/preview.scss +++ b/src/views/preview/preview.scss @@ -32,6 +32,14 @@ $stage-width: 480px; transform: translate(22rem, 0); } } + + &.no-edit { + /* titles of projects you don't own should not + show the full title if this is too long */ + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } } .project-header { @@ -39,6 +47,8 @@ $stage-width: 480px; flex-grow: 1; justify-content: flex-start; align-items: flex-start; + flex-wrap: nowrap; + width: 65%; /* Setting a width to the header will keep it from flowing over the usual content of the page */ .inplace-input { height: calc(3rem - 4px); @@ -66,9 +76,10 @@ $stage-width: 480px; text-align: left; font-size: .8rem; flex-grow: 1; + width: inherit; /* Inherits the width of whatever this is in. This works well for the preview page and might need to change if used in a different context*/ } - .validation-message { + .validation-message { $arrow-border-width: 1rem; display: block; position: absolute; From befa5485bb523931a754a0ebcde1bf26057b9853 Mon Sep 17 00:00:00 2001 From: Linda Date: Thu, 23 Aug 2018 14:31:44 -0400 Subject: [PATCH 20/60] some ordering of css stuff fixed --- src/views/preview/preview.scss | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/views/preview/preview.scss b/src/views/preview/preview.scss index 9e6c98d1c..e2dbd84f7 100644 --- a/src/views/preview/preview.scss +++ b/src/views/preview/preview.scss @@ -44,11 +44,11 @@ $stage-width: 480px; .project-header { margin-right: 2rem; + width: 65%; /* Setting a width to the header will keep it from flowing over the usual content of the page */ flex-grow: 1; justify-content: flex-start; align-items: flex-start; flex-wrap: nowrap; - width: 65%; /* Setting a width to the header will keep it from flowing over the usual content of the page */ .inplace-input { height: calc(3rem - 4px); @@ -73,13 +73,13 @@ $stage-width: 480px; .title { margin-left: 1rem; + width: inherit; /* Inherits the width of whatever this is in. This works well for the preview page and might need to change if used in a different context*/ text-align: left; font-size: .8rem; flex-grow: 1; - width: inherit; /* Inherits the width of whatever this is in. This works well for the preview page and might need to change if used in a different context*/ } - .validation-message { + .validation-message { $arrow-border-width: 1rem; display: block; position: absolute; From ba919062f341ce56bf6f103916a359fced2aafba Mon Sep 17 00:00:00 2001 From: Linda Date: Fri, 24 Aug 2018 08:41:37 -0400 Subject: [PATCH 21/60] changed look of studio thumbnails --- .../thumbnailcolumn/thumbnailcolumn.scss | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/components/thumbnailcolumn/thumbnailcolumn.scss b/src/components/thumbnailcolumn/thumbnailcolumn.scss index daa9ed0d7..d9e619b0c 100644 --- a/src/components/thumbnailcolumn/thumbnailcolumn.scss +++ b/src/components/thumbnailcolumn/thumbnailcolumn.scss @@ -5,10 +5,10 @@ $thumbnail-width: 220px; $thumbnail-inner-width: 204px; - + $project-height: 208px; $gallery-height: 164px; - + margin: 0 auto; padding: 12px 0; justify-content: flex-start; @@ -16,15 +16,19 @@ .thumbnail { margin: 7px; - border-radius: 4px; - box-shadow: 0 0 0 1px $active-gray; - background-color: $ui-white; + // adding the following commented lines to thumbnail-image + // border-radius: 4px; + // box-shadow: 0 0 0 1px $active-gray; + // background-color: $ui-white; padding-bottom: 4px; width: $thumbnail-width; .thumbnail-image { margin: 8px auto; width: $thumbnail-inner-width; + border-radius: 4px; + box-shadow: 0 0 0 1px $active-gray; + background-color: $ui-white; } .thumbnail-info { @@ -45,10 +49,18 @@ .thumbnail-title { float: left; max-width: 164px; + overflow: hidden; .thumbnail-creator a { color: $type-gray; } + + a { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + word-wrap: break-word; + } } } From 79e80aea543618e89874c19aa6b71feedbac873e Mon Sep 17 00:00:00 2001 From: Linda Date: Fri, 24 Aug 2018 09:05:08 -0400 Subject: [PATCH 22/60] improved remix and studio row --- src/components/thumbnailcolumn/thumbnailcolumn.scss | 7 ++----- src/views/preview/preview.scss | 10 +++++++++- src/views/preview/remix-list.jsx | 4 ++-- src/views/preview/studio-list.jsx | 6 +++--- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/components/thumbnailcolumn/thumbnailcolumn.scss b/src/components/thumbnailcolumn/thumbnailcolumn.scss index d9e619b0c..4e0dbba70 100644 --- a/src/components/thumbnailcolumn/thumbnailcolumn.scss +++ b/src/components/thumbnailcolumn/thumbnailcolumn.scss @@ -16,11 +16,8 @@ .thumbnail { margin: 7px; - // adding the following commented lines to thumbnail-image - // border-radius: 4px; - // box-shadow: 0 0 0 1px $active-gray; - // background-color: $ui-white; - padding-bottom: 4px; + // unnecessary: + // padding-bottom: 4px; width: $thumbnail-width; .thumbnail-image { diff --git a/src/views/preview/preview.scss b/src/views/preview/preview.scss index 8aefd8ead..7674facab 100644 --- a/src/views/preview/preview.scss +++ b/src/views/preview/preview.scss @@ -486,8 +486,16 @@ $stage-width: 480px; .studio-list { flex-direction: column; + h2 { + align-self: flex-start; + margin-left: 1rem; + font-size: 1.2rem; + font-weight: bold; + } + .project { - margin-bottom: 1.5rem; + // not necessary: + // margin-bottom: 1.5rem; } .creator-image img { diff --git a/src/views/preview/remix-list.jsx b/src/views/preview/remix-list.jsx index a207d8cbe..14e7d1353 100644 --- a/src/views/preview/remix-list.jsx +++ b/src/views/preview/remix-list.jsx @@ -9,9 +9,9 @@ const RemixList = props => { if (remixes.length === 0) return null; return ( -
    +

    Remixes -

    + {remixes.length === 0 ? ( // TODO: style remix invitation Invite user to remix diff --git a/src/views/preview/studio-list.jsx b/src/views/preview/studio-list.jsx index 89998980b..bdacd576e 100644 --- a/src/views/preview/studio-list.jsx +++ b/src/views/preview/studio-list.jsx @@ -8,10 +8,10 @@ const StudioList = props => { const studios = props.studios; if (studios.length === 0) return null; return ( - -
    + +

    Studios -

    + {studios.length === 0 ? ( // TODO: style remix invitation Invite user to add to studio From d95ee37c044494329ba61e9e7e14422a8adaa679 Mon Sep 17 00:00:00 2001 From: Linda Date: Fri, 24 Aug 2018 09:09:17 -0400 Subject: [PATCH 23/60] now you can see the full title of something when hovering over the title which might be cut off --- src/components/thumbnail/thumbnail.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/thumbnail/thumbnail.jsx b/src/components/thumbnail/thumbnail.jsx index 300c65955..461cd67b1 100644 --- a/src/components/thumbnail/thumbnail.jsx +++ b/src/components/thumbnail/thumbnail.jsx @@ -74,6 +74,7 @@ const Thumbnail = props => {
    {props.title} From 10aa57e4a2740d4002996d292c4d61b15e6759bb Mon Sep 17 00:00:00 2001 From: Linda Date: Fri, 24 Aug 2018 09:25:04 -0400 Subject: [PATCH 24/60] fixed ordering and so in css --- src/components/thumbnailcolumn/thumbnailcolumn.scss | 2 +- src/views/preview/preview.scss | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/thumbnailcolumn/thumbnailcolumn.scss b/src/components/thumbnailcolumn/thumbnailcolumn.scss index 4e0dbba70..0398157b0 100644 --- a/src/components/thumbnailcolumn/thumbnailcolumn.scss +++ b/src/components/thumbnailcolumn/thumbnailcolumn.scss @@ -22,10 +22,10 @@ .thumbnail-image { margin: 8px auto; - width: $thumbnail-inner-width; border-radius: 4px; box-shadow: 0 0 0 1px $active-gray; background-color: $ui-white; + width: $thumbnail-inner-width; } .thumbnail-info { diff --git a/src/views/preview/preview.scss b/src/views/preview/preview.scss index 7674facab..218d9f9be 100644 --- a/src/views/preview/preview.scss +++ b/src/views/preview/preview.scss @@ -487,14 +487,14 @@ $stage-width: 480px; flex-direction: column; h2 { - align-self: flex-start; - margin-left: 1rem; - font-size: 1.2rem; - font-weight: bold; + margin-left: 1rem; + font-size: 1.2rem; + font-weight: bold; + align-self: flex-start; } .project { - // not necessary: + // not necessary: // margin-bottom: 1.5rem; } From 919910f30aa1cd51fac120e432e6225cca77aa47 Mon Sep 17 00:00:00 2001 From: Linda Date: Fri, 24 Aug 2018 13:14:22 -0400 Subject: [PATCH 25/60] made empty space next to comments section a bit smaller --- src/views/preview/preview.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/preview/preview.scss b/src/views/preview/preview.scss index 8aefd8ead..fc0e5f265 100644 --- a/src/views/preview/preview.scss +++ b/src/views/preview/preview.scss @@ -124,7 +124,7 @@ $stage-width: 480px; } .comments-container { - width: 60%; + width: 65%; } .remix-button, From 733134c4212850a727249e980b2b97fed415081b Mon Sep 17 00:00:00 2001 From: Ben Wheeler Date: Fri, 24 Aug 2018 18:04:57 -0400 Subject: [PATCH 26/60] pass through logout callback to GUI --- src/components/navigation/www/accountnav.jsx | 6 +- src/components/navigation/www/accountnav.scss | 91 +++++++++++++++++++ src/components/navigation/www/navigation.jsx | 2 + src/components/navigation/www/navigation.scss | 69 -------------- src/views/preview/preview.jsx | 20 +++- 5 files changed, 115 insertions(+), 73 deletions(-) create mode 100644 src/components/navigation/www/accountnav.scss diff --git a/src/components/navigation/www/accountnav.jsx b/src/components/navigation/www/accountnav.jsx index 1f8c8cc9d..70e90f6fd 100644 --- a/src/components/navigation/www/accountnav.jsx +++ b/src/components/navigation/www/accountnav.jsx @@ -7,7 +7,7 @@ const React = require('react'); const Avatar = require('../../avatar/avatar.jsx'); const Dropdown = require('../../dropdown/dropdown.jsx'); -require('./navigation.scss'); +require('./accountnav.scss'); const AccountNav = ({ classroomId, @@ -21,7 +21,7 @@ const AccountNav = ({ onClickLogout, onClose }) => ( - +
  • - +
    ); AccountNav.propTypes = { diff --git a/src/components/navigation/www/accountnav.scss b/src/components/navigation/www/accountnav.scss new file mode 100644 index 000000000..ffa0e1a11 --- /dev/null +++ b/src/components/navigation/www/accountnav.scss @@ -0,0 +1,91 @@ +@import "../../../colors"; +@import "../../../frameless"; + +#account-nav { + .user-info { + display: inline-block; + padding: 14px 15px 4px 15px; + max-width: 260px; + height: 33px; + overflow: hidden; + text-decoration: none; + text-overflow: ellipsis; + white-space: nowrap; + color: $type-white; + font-size: .8125rem; + font-weight: normal; + + .avatar { + margin-right: 10px; + border-radius: 3px; + width: 24px; + height: 24px; + vertical-align: middle; + } + + &:hover { + background-color: $active-gray; + } + + &.open { + background-color: $active-gray; + } + + &:after { + display: inline-block; + margin-left: 8px; + + background-image: url("/images/dropdown.png"); + background-repeat: no-repeat; + background-position: center center; + background-size: 50%; + width: 20px; + height: 20px; + vertical-align: middle; + content: " "; + } + } + + .dropdown { + top: 50px; + padding: 0; + padding-top: 5px; + width: 100%; + box-sizing: border-box; + } +} + +//4 columns +@media only screen and (max-width: $mobile - 1) { + #account-nav { + .user-info { + .avatar { + margin-right: 0; + } + + &:after { + display: none; + } + } + } +} + + +//6 columns +@media only screen and (min-width: $mobile) and (max-width: $tablet - 1) { + #account-nav { + .user-info { + .avatar { + margin-right: 0; + } + + &:after { + display: none; + } + } + } +} + +//8 columns +@media only screen and (min-width: $tablet) and (max-width: $desktop - 1) { +} diff --git a/src/components/navigation/www/navigation.jsx b/src/components/navigation/www/navigation.jsx index 78de52873..4eb2c26e9 100644 --- a/src/components/navigation/www/navigation.jsx +++ b/src/components/navigation/www/navigation.jsx @@ -113,6 +113,8 @@ class Navigation extends React.Component { handleCloseLogin () { this.setState({loginOpen: false}); } + // NOTE: TODO: continue here. Should move these two functions up to a redux level, + // maybe into session... handleLogIn (formData, callback) { this.setState({loginError: null}); formData.useMessages = true; diff --git a/src/components/navigation/www/navigation.scss b/src/components/navigation/www/navigation.scss index cfa5a72c1..c867750be 100644 --- a/src/components/navigation/www/navigation.scss +++ b/src/components/navigation/www/navigation.scss @@ -182,55 +182,6 @@ } } } - - .account-nav { - .user-info { - padding-top: 14px; - max-width: 260px; - } - - > a { - display: inline-block; - overflow: hidden; - text-overflow: ellipsis; - font-size: .8125rem; - font-weight: normal; - - .avatar { - margin-right: 10px; - border-radius: 3px; - width: 24px; - height: 24px; - vertical-align: middle; - } - - &.open { - background-color: $active-gray; - } - - &:after { - display: inline-block; - margin-left: 8px; - - background-image: url("/images/dropdown.png"); - background-repeat: no-repeat; - background-position: center center; - background-size: 50%; - width: 20px; - height: 20px; - vertical-align: middle; - content: " "; - } - } - - .dropdown { - top: 50px; - padding: 0; - padding-top: 5px; - width: 100%; - box-sizing: border-box; - } - } } //4 columns @@ -245,16 +196,6 @@ &.account-nav { margin-left: 0; - - > a { - .avatar { - margin-right: 0; - } - - &:after { - display: none; - } - } } } @@ -283,16 +224,6 @@ &.account-nav { margin-left: 0; - - > a { - .avatar { - margin-right: 0; - } - - &:after { - display: none; - } - } } } diff --git a/src/views/preview/preview.jsx b/src/views/preview/preview.jsx index d221c2513..a9bb1275e 100644 --- a/src/views/preview/preview.jsx +++ b/src/views/preview/preview.jsx @@ -8,6 +8,7 @@ const connect = require('react-redux').connect; const injectIntl = require('react-intl').injectIntl; const parser = require('scratch-parser'); const Page = require('../../components/page/www/page.jsx'); +const api = require('../../lib/api'); const render = require('../../lib/render.jsx'); const storage = require('../../lib/storage.js').default; const log = require('../../lib/log'); @@ -30,6 +31,8 @@ class Preview extends React.Component { 'handleToggleStudio', 'handleFavoriteToggle', 'handleLoadMore', + // temporary, to pass to GUI. Remove when nav bar components are shared between www and gui. + 'handleLogout', 'handleLoveToggle', 'handlePermissions', 'handlePopState', @@ -141,6 +144,21 @@ class Preview extends React.Component { }); }); } + // Temporarily duplicated this function from navigation.jsx here. + // Should move handling of login/logout into session.js, and handle them + // from here as well as navigation.jsx. + handleLogout (e) { + e.preventDefault(); + api({ + host: '', + method: 'post', + uri: '/accounts/logout/', + useCsrf: true + }, err => { + if (err) log.error(err); + window.location = '/'; + }); + } handleReportClick () { this.setState({reportOpen: true}); } @@ -315,7 +333,6 @@ class Preview extends React.Component { replies={this.props.replies} reportOpen={this.state.reportOpen} studios={this.props.studios} - user={this.props.user} userOwnsProject={this.userOwnsProject()} onAddToStudioClicked={this.handleAddToStudioClick} onAddToStudioClosed={this.handleAddToStudioClose} @@ -339,6 +356,7 @@ class Preview extends React.Component { className="gui" projectHost={this.props.projectHost} projectId={this.state.projectId} + onClickLogout={this.handleLogout} /> ); } From 0ef4eca0bb3bf9f4351608b6cb9b327878b06cf7 Mon Sep 17 00:00:00 2001 From: Linda Date: Tue, 28 Aug 2018 09:33:06 -0400 Subject: [PATCH 27/60] improved wording --- src/views/ev3/l10n.json | 17 ++++++++--------- src/views/microbit/l10n.json | 6 +++--- src/views/wedo2/l10n.json | 6 +++--- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/views/ev3/l10n.json b/src/views/ev3/l10n.json index d1a79b471..58a815c8f 100644 --- a/src/views/ev3/l10n.json +++ b/src/views/ev3/l10n.json @@ -35,14 +35,13 @@ "ev3.updateFirmwareTitle": "Try updating your EV3 firmware", "ev3.updateFirmwareText": "We recommend updating to EV3 firmware version 1.10E or above. See {firmwareUpdateLink}.", "ev3.firmwareUpdateText": "firmware update instructions from LEGO", - "ev3.imgAltEv3Illustration": "Illustration of an EV3 Computer featuring some examples of interacting with an EV3.", - "ev3.imgAltAddExtension": "In the editor, click on the \"Add Extensions\" button on the lower left.", - "ev3.imgAltAcceptConnection": "Use the buttons of your EV3 to accept the connection.", - "ev3.imgAltAcceptPasscode": "Use the center button of your EV3 to accept the passcode.", - "ev3.imgAltWaitForWindows": "Windows notifies you when EV3 is ready.", + "ev3.imgAltEv3Illustration": "Illustration of an EV3 hub, featuring some examples of interacting with it.", + "ev3.imgAltAcceptConnection": "Use the buttons on your EV3 to accept the connection.", + "ev3.imgAltAcceptPasscode": "Use the center button on your EV3 to accept the passcode.", + "ev3.imgAltWaitForWindows": "Windows will notify you when the EV3 is ready.", "ev3.imgAltEnterPasscodeMac": "Enter the passcode into the connection request window opening on your Mac.", - "ev3.imgAltPlugInMotor": "Port A is not to be confused with Port 4 on the other side of the EV3.", - "ev3.imgAltWaveHello": "Example of a Scratch project with a waving fairy.", - "ev3.imgAltDistanceInstrument": "Example of a Scratch project with a guitar.", - "ev3.imgAltSpaceTacos": "Example of a Scratch project with Scratch Cat and a taco in space." + "ev3.imgAltPlugInMotor": "To find port A: hold the EV3 with the screen and buttons facing you, with the screen above the buttons. Port A is on top, and it is the left-most one", + "ev3.imgAltWaveHello": "A Scratch project with a waving fairy.", + "ev3.imgAltDistanceInstrument": "A Scratch project with a guitar.", + "ev3.imgAltSpaceTacos": "A Scratch project with Scratch Cat and a taco in space." } diff --git a/src/views/microbit/l10n.json b/src/views/microbit/l10n.json index 871ef7016..388db9497 100644 --- a/src/views/microbit/l10n.json +++ b/src/views/microbit/l10n.json @@ -32,7 +32,7 @@ "microbit.imgAltMicrobitIllustration": "Illustration of the micro:bit circuit board.", "microbit.imgAltDragDropHex": "Drag and drop the HEX file from the folder you downloaded it to to the micro:bit.", "microbit.imgAltDisplayH": "A micro:bit displaying an H.", - "microbit.imgAltHeartBeat" : "An example project with a heart.", - "microbit.imgAltTiltGuitar": "An example project with a guitar.", - "microbit.imgAltOceanAdventure": "An example project with a clown fish and a saxophone under water." + "microbit.imgAltHeartBeat" : "A Scratch project with a heart.", + "microbit.imgAltTiltGuitar": "A Scratch project with a guitar.", + "microbit.imgAltOceanAdventure": "A Scratch project with a clown fish and a saxophone under water." } diff --git a/src/views/wedo2/l10n.json b/src/views/wedo2/l10n.json index 5736298fc..0adfcd2df 100644 --- a/src/views/wedo2/l10n.json +++ b/src/views/wedo2/l10n.json @@ -25,7 +25,7 @@ "wedo2.legacyInfoText": "Visit our page about {wedoLegacyLink}.", "wedo2.legacyLinkText": "using LEGO WeDo with Scratch 2.0", "wedo2.imgAltWeDoIllustration": "An illustration of a WeDo2 featuring a tilt sensor and a motor.", - "wedo2.imgAltStarter1": "An example project with a dog and a taco.", - "wedo2.imgAltStarter2": "An example project with a toad playing instruments in space.", - "wedo2.imgAltStarter3": "An example project with dinosaurs." + "wedo2.imgAltStarter1": "A Scratch project with a dog and a taco.", + "wedo2.imgAltStarter2": "A Scratch project with a toad playing instruments in space.", + "wedo2.imgAltStarter3": "A Scratch project with dinosaurs." } From 3863e9c5bf1dc10e04e474d7eb998a97c1289268 Mon Sep 17 00:00:00 2001 From: Linda Date: Tue, 28 Aug 2018 16:50:34 -0400 Subject: [PATCH 28/60] remove unnecessary comments --- src/components/thumbnailcolumn/thumbnailcolumn.scss | 2 -- src/views/preview/preview.scss | 5 ----- 2 files changed, 7 deletions(-) diff --git a/src/components/thumbnailcolumn/thumbnailcolumn.scss b/src/components/thumbnailcolumn/thumbnailcolumn.scss index 0398157b0..5e146aa67 100644 --- a/src/components/thumbnailcolumn/thumbnailcolumn.scss +++ b/src/components/thumbnailcolumn/thumbnailcolumn.scss @@ -16,8 +16,6 @@ .thumbnail { margin: 7px; - // unnecessary: - // padding-bottom: 4px; width: $thumbnail-width; .thumbnail-image { diff --git a/src/views/preview/preview.scss b/src/views/preview/preview.scss index 218d9f9be..defa052f9 100644 --- a/src/views/preview/preview.scss +++ b/src/views/preview/preview.scss @@ -493,11 +493,6 @@ $stage-width: 480px; align-self: flex-start; } - .project { - // not necessary: - // margin-bottom: 1.5rem; - } - .creator-image img { max-width: 2rem; max-height: 2rem; From affdc7e67075bc3f940f5337b2814cce4ccf9c57 Mon Sep 17 00:00:00 2001 From: Linda Date: Tue, 28 Aug 2018 17:01:36 -0400 Subject: [PATCH 29/60] use specific class instead of h2 --- src/views/preview/preview.scss | 2 +- src/views/preview/remix-list.jsx | 4 ++-- src/views/preview/studio-list.jsx | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/views/preview/preview.scss b/src/views/preview/preview.scss index defa052f9..d030640da 100644 --- a/src/views/preview/preview.scss +++ b/src/views/preview/preview.scss @@ -486,7 +486,7 @@ $stage-width: 480px; .studio-list { flex-direction: column; - h2 { + .list-title { margin-left: 1rem; font-size: 1.2rem; font-weight: bold; diff --git a/src/views/preview/remix-list.jsx b/src/views/preview/remix-list.jsx index 14e7d1353..f9fb4d7c3 100644 --- a/src/views/preview/remix-list.jsx +++ b/src/views/preview/remix-list.jsx @@ -9,9 +9,9 @@ const RemixList = props => { if (remixes.length === 0) return null; return ( -

    +
    Remixes -

    +
    {remixes.length === 0 ? ( // TODO: style remix invitation Invite user to remix diff --git a/src/views/preview/studio-list.jsx b/src/views/preview/studio-list.jsx index bdacd576e..dbb4f1417 100644 --- a/src/views/preview/studio-list.jsx +++ b/src/views/preview/studio-list.jsx @@ -9,9 +9,9 @@ const StudioList = props => { if (studios.length === 0) return null; return ( -

    +
    Studios -

    +
    {studios.length === 0 ? ( // TODO: style remix invitation Invite user to add to studio From b0ecae351e2032bb142f522ad4dee5712854daf1 Mon Sep 17 00:00:00 2001 From: Linda Date: Thu, 30 Aug 2018 15:37:51 -0400 Subject: [PATCH 30/60] prevented the project title from overflowing in a way more elegant way --- src/views/preview/preview.scss | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/views/preview/preview.scss b/src/views/preview/preview.scss index fa15e68f4..eebbffec5 100644 --- a/src/views/preview/preview.scss +++ b/src/views/preview/preview.scss @@ -44,7 +44,7 @@ $stage-width: 480px; .project-header { margin-right: 2rem; - width: 65%; /* Setting a width to the header will keep it from flowing over the usual content of the page */ + min-width: 0; flex-grow: 1; justify-content: flex-start; align-items: flex-start; @@ -73,7 +73,8 @@ $stage-width: 480px; .title { margin-left: 1rem; - width: inherit; /* Inherits the width of whatever this is in. This works well for the preview page and might need to change if used in a different context*/ + /* width: inherit; Inherits the width of whatever this is in. This works well for the preview page and might need to change if used in a different context*/ + min-width: 0; text-align: left; font-size: .8rem; flex-grow: 1; @@ -130,6 +131,10 @@ $stage-width: 480px; } } + .project-buttons { + flex-shrink: 0; + } + .button { margin-left: 1rem; } From d78ee1fe7c82d06110fe887fbb7734ea80198711 Mon Sep 17 00:00:00 2001 From: Linda Date: Thu, 30 Aug 2018 15:44:17 -0400 Subject: [PATCH 31/60] some linting --- src/views/preview/preview.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/views/preview/preview.scss b/src/views/preview/preview.scss index eebbffec5..a090ee077 100644 --- a/src/views/preview/preview.scss +++ b/src/views/preview/preview.scss @@ -132,7 +132,7 @@ $stage-width: 480px; } .project-buttons { - flex-shrink: 0; + flex-shrink: 0; } .button { @@ -458,6 +458,7 @@ $stage-width: 480px; content: ""; } } + .studio-button { &:before { background-image: url("/svgs/project/studio-add-white.svg"); From 0f2ca09892dc4d7df7865c21821fad90ef884568 Mon Sep 17 00:00:00 2001 From: Linda Date: Tue, 4 Sep 2018 12:54:29 -0400 Subject: [PATCH 32/60] added Katelyn to credits page --- src/views/credits/credits.jsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/views/credits/credits.jsx b/src/views/credits/credits.jsx index cdf43e0a5..5301f63e1 100644 --- a/src/views/credits/credits.jsx +++ b/src/views/credits/credits.jsx @@ -29,7 +29,7 @@ const Credits = () => ( /> Carl Bowman - +
  • Karishma Avatar ( DD Liu
  • +
  • + Katelyn Avatar + Katelyn Mann +
  • +
  • Shruti Avatar (

  • ); - + render(, document.getElementById('app')); From f9003077a3f4131a212696c826fa04357388244b Mon Sep 17 00:00:00 2001 From: Ben Wheeler Date: Tue, 4 Sep 2018 17:15:52 -0400 Subject: [PATCH 33/60] use account-nav class, not account-nav id --- src/components/navigation/www/accountnav.jsx | 2 +- src/components/navigation/www/accountnav.scss | 13 ++++++++++--- src/components/navigation/www/navigation.scss | 11 +---------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/components/navigation/www/accountnav.jsx b/src/components/navigation/www/accountnav.jsx index 70e90f6fd..a0d441626 100644 --- a/src/components/navigation/www/accountnav.jsx +++ b/src/components/navigation/www/accountnav.jsx @@ -21,7 +21,7 @@ const AccountNav = ({ onClickLogout, onClose }) => ( -
    +
    ul > li { - &.login-item, - &.account-nav { + &.login-item { margin-left: 0; } } From 4bf0964bf2f5c066a63c0ad666042f61e32ab7ba Mon Sep 17 00:00:00 2001 From: Ben Wheeler Date: Wed, 5 Sep 2018 16:53:30 -0400 Subject: [PATCH 34/60] moved dispatched navigation function calls to mapDispatchToProps --- src/components/navigation/www/navigation.jsx | 27 +++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/components/navigation/www/navigation.jsx b/src/components/navigation/www/navigation.jsx index 4eb2c26e9..dffd88fc4 100644 --- a/src/components/navigation/www/navigation.jsx +++ b/src/components/navigation/www/navigation.jsx @@ -54,9 +54,7 @@ class Navigation extends React.Component { componentDidMount () { if (this.props.session.session.user) { const intervalId = setInterval(() => { - this.props.dispatch( - messageCountActions.getCount(this.props.session.session.user.username) - ); + this.props.getMessageCount(this.props.session.session.user.username); }, 120000); // check for new messages every 2 mins. this.setState({ // eslint-disable-line react/no-did-mount-set-state messageCountIntervalId: intervalId @@ -71,9 +69,7 @@ class Navigation extends React.Component { }); if (this.props.session.session.user) { const intervalId = setInterval(() => { - this.props.dispatch( - messageCountActions.getCount(this.props.session.session.user.username) - ); + this.props.getMessageCount(this.props.session.session.user.username); }, 120000); // check for new messages every 2 mins. this.setState({ // eslint-disable-line react/no-did-update-set-state messageCountIntervalId: intervalId @@ -81,7 +77,7 @@ class Navigation extends React.Component { } else { // clear message count check, and set to default id. clearInterval(this.state.messageCountIntervalId); - this.props.dispatch(messageCountActions.setCount(0)); + this.props.setMessageCount(0); this.setState({ // eslint-disable-line react/no-did-update-set-state messageCountIntervalId: -1 }); @@ -135,7 +131,7 @@ class Navigation extends React.Component { this.showCanceledDeletion(); } }); - this.props.dispatch(sessionActions.refreshSession()); + this.props.refreshSession(); } else { if (body.redirect) { window.location = body.redirect; @@ -356,6 +352,7 @@ class Navigation extends React.Component { Navigation.propTypes = { dispatch: PropTypes.func, + getMessageCount: PropTypes.func, intl: intlShape, permissions: PropTypes.shape({ admin: PropTypes.bool, @@ -364,6 +361,7 @@ Navigation.propTypes = { educator_invitee: PropTypes.bool, student: PropTypes.bool }), + refreshSession: PropTypes.func, searchTerm: PropTypes.string, session: PropTypes.shape({ session: PropTypes.shape({ @@ -375,6 +373,7 @@ Navigation.propTypes = { }), status: PropTypes.string }), + setMessageCount: PropTypes.func, unreadMessageCount: PropTypes.oneOfType([PropTypes.number, PropTypes.string]) }; @@ -391,7 +390,17 @@ const mapStateToProps = state => ({ searchTerm: state.navigation }); -const mapDispatchToProps = () => ({}); +const mapDispatchToProps = dispatch => ({ + getMessageCount: username => { + dispatch(messageCountActions.getCount(username)); + }, + refreshSession: () => { + dispatch(sessionActions.refreshSession()); + }, + setMessageCount: newCount => { + dispatch(messageCountActions.setCount(newCount)); + } +}); const ConnectedNavigation = connect( mapStateToProps, From 478a30efcb03de87e05116eab6925e9ca3f32ec2 Mon Sep 17 00:00:00 2001 From: Ben Wheeler Date: Mon, 27 Aug 2018 17:11:05 -0400 Subject: [PATCH 35/60] pass project title to GUI, and disable submit when editing title --- src/lib/render.jsx | 2 +- src/views/preview/presentation.jsx | 13 ++++++++++++- src/views/preview/preview.jsx | 8 +++++++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/lib/render.jsx b/src/lib/render.jsx index 3bbc66743..dce966204 100644 --- a/src/lib/render.jsx +++ b/src/lib/render.jsx @@ -37,7 +37,7 @@ const render = (jsx, element, reducers, initialState, enhancer) => { } const allReducers = reducer(reducers); - + const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || redux.compose; const enhancers = enhancer ? composeEnhancers( diff --git a/src/views/preview/presentation.jsx b/src/views/preview/presentation.jsx index bffa0f829..9390120ff 100644 --- a/src/views/preview/presentation.jsx +++ b/src/views/preview/presentation.jsx @@ -27,6 +27,16 @@ const ExtensionChip = require('./extension-chip.jsx'); const projectShape = require('./projectshape.jsx').projectShape; require('./preview.scss'); +// disable enter key submission on formsy input fields; otherwise formsy thinks +// we meant to trigger the "See inside" button. Instead, treat these keypresses +// as a blur, which will trigger a save. +const onKeyPress = e => { + if (e.target.type === 'text' && e.which === 13 /* Enter */) { + e.preventDefault(); + e.target.blur(); + } +}; + const PreviewPresentation = ({ assetHost, backpackOptions, @@ -70,7 +80,7 @@ const PreviewPresentation = ({ { projectInfo && projectInfo.author && projectInfo.author.id && ( - +
    @@ -135,6 +145,7 @@ const PreviewPresentation = ({ previewInfoVisible="false" projectHost={projectHost} projectId={projectId} + projectTitle={projectInfo.title} />
    diff --git a/src/views/preview/preview.jsx b/src/views/preview/preview.jsx index a9bb1275e..59f79cccc 100644 --- a/src/views/preview/preview.jsx +++ b/src/views/preview/preview.jsx @@ -42,6 +42,7 @@ class Preview extends React.Component { 'handleAddToStudioClick', 'handleAddToStudioClose', 'handleSeeInside', + 'handleUpdateProjectTitle', 'handleUpdate', 'initCounts', 'isShared', @@ -277,6 +278,11 @@ class Preview extends React.Component { this.props.user.token ); } + handleUpdateProjectTitle (title) { + this.handleUpdate({ + title: title + }); + } initCounts (favorites, loves) { this.setState({ favoriteCount: favorites, @@ -456,7 +462,6 @@ const consolidateStudiosInfo = (curatedStudios, projectStudios, currentStudioIds }; const mapStateToProps = state => ({ - projectInfo: state.preview.projectInfo, comments: state.preview.comments, faved: state.preview.faved, loved: state.preview.loved, @@ -465,6 +470,7 @@ const mapStateToProps = state => ({ remixes: state.preview.remixes, replies: state.preview.replies, sessionStatus: state.session.status, + projectInfo: state.preview.projectInfo, projectStudios: state.preview.projectStudios, studios: consolidateStudiosInfo(state.preview.curatedStudios, state.preview.projectStudios, state.preview.currentStudioIds, From 2f5604d23d97e7f38af49f442981aa81ac7f2696 Mon Sep 17 00:00:00 2001 From: Ben Wheeler Date: Tue, 4 Sep 2018 14:29:59 -0400 Subject: [PATCH 36/60] localized Title too long error string --- src/views/preview/l10n.json | 1 + src/views/preview/presentation.jsx | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/views/preview/l10n.json b/src/views/preview/l10n.json index 4dead1d4a..59f304b7c 100644 --- a/src/views/preview/l10n.json +++ b/src/views/preview/l10n.json @@ -1,6 +1,7 @@ { "addToStudio.title": "Add to Studio", "addToStudio.finishing": "Finishing up...", + "preview.titleMaxLength": "Title is too long", "preview.musicExtensionChip": "Music", "preview.penExtensionChip": "Pen", "preview.speechExtensionChip": "Google Speech", diff --git a/src/views/preview/presentation.jsx b/src/views/preview/presentation.jsx index 9390120ff..bcab17902 100644 --- a/src/views/preview/presentation.jsx +++ b/src/views/preview/presentation.jsx @@ -1,6 +1,7 @@ const FormattedDate = require('react-intl').FormattedDate; const injectIntl = require('react-intl').injectIntl; const PropTypes = require('prop-types'); +const intlShape = require('react-intl').intlShape; const React = require('react'); const Formsy = require('formsy-react').default; const classNames = require('classnames'); @@ -45,6 +46,7 @@ const PreviewPresentation = ({ extensions, faved, favoriteCount, + intl, isFullScreen, isLoggedIn, isShared, @@ -98,10 +100,9 @@ const PreviewPresentation = ({ handleUpdate={onUpdate} name="title" validationErrors={{ - maxLength: 'Sorry title is too long' - // maxLength: props.intl.formatMessage({ - // id: 'project.titleMaxLength' - // }) + maxLength: intl.formatMessage({ + id: 'preview.titleMaxLength' + }) }} validations={{ maxLength: 100 @@ -376,6 +377,7 @@ PreviewPresentation.propTypes = { extensions: PropTypes.arrayOf(PropTypes.object), faved: PropTypes.bool, favoriteCount: PropTypes.number, + intl: intlShape, isFullScreen: PropTypes.bool, isLoggedIn: PropTypes.bool, isShared: PropTypes.bool, From 2a19bb283f3fecd2219c6bb11291fd384a9d7ec6 Mon Sep 17 00:00:00 2001 From: Ben Wheeler Date: Thu, 6 Sep 2018 16:54:12 -0400 Subject: [PATCH 37/60] no need to pass title to embedded gui --- src/views/preview/presentation.jsx | 1 - src/views/preview/preview.jsx | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/views/preview/presentation.jsx b/src/views/preview/presentation.jsx index bcab17902..56727130e 100644 --- a/src/views/preview/presentation.jsx +++ b/src/views/preview/presentation.jsx @@ -146,7 +146,6 @@ const PreviewPresentation = ({ previewInfoVisible="false" projectHost={projectHost} projectId={projectId} - projectTitle={projectInfo.title} />
    diff --git a/src/views/preview/preview.jsx b/src/views/preview/preview.jsx index 59f79cccc..6b3fe2909 100644 --- a/src/views/preview/preview.jsx +++ b/src/views/preview/preview.jsx @@ -362,7 +362,9 @@ class Preview extends React.Component { className="gui" projectHost={this.props.projectHost} projectId={this.state.projectId} + projectTitle={this.props.projectInfo.title} onClickLogout={this.handleLogout} + onUpdateProjectTitle={this.handleUpdateProjectTitle} /> ); } From ed604a21d4dbb7c82d9e2e9272cf59a96a5e59df Mon Sep 17 00:00:00 2001 From: Linda Date: Fri, 7 Sep 2018 09:26:11 -0400 Subject: [PATCH 38/60] add studio buttons animation on preview page, need fixing --- .../modal/addtostudio/animate-hoc.jsx | 34 +++++++++ src/components/modal/addtostudio/modal.scss | 75 ++++++++++++++----- .../modal/addtostudio/studio-button.jsx | 33 +++++--- 3 files changed, 114 insertions(+), 28 deletions(-) create mode 100644 src/components/modal/addtostudio/animate-hoc.jsx diff --git a/src/components/modal/addtostudio/animate-hoc.jsx b/src/components/modal/addtostudio/animate-hoc.jsx new file mode 100644 index 000000000..02f436f8c --- /dev/null +++ b/src/components/modal/addtostudio/animate-hoc.jsx @@ -0,0 +1,34 @@ +const React = require('react'); +const PropTypes = require('prop-types'); + +/** + * Higher-order component for building an animated studio button + * @param {React.Component} Component a studio button component + * @return {React.Component} a wrapped studio button component + */ + +const AnimateHOC = ({ + Component +}) => { + class WrappedComponent extends React.Component { + constructor(props) { + super(props); + let wasClicked = false; + } + onClick () { + this.wasClicked = true; // BUT PROPS ARE READONLY? + } + render () { + return (); + } + } + + return WrappedComponent; +}; + +AnimateHOC.propTypes = { + Component: PropTypes.element +}; diff --git a/src/components/modal/addtostudio/modal.scss b/src/components/modal/addtostudio/modal.scss index 4ec0bc71b..f4914d45b 100644 --- a/src/components/modal/addtostudio/modal.scss +++ b/src/components/modal/addtostudio/modal.scss @@ -89,7 +89,6 @@ pointer-events: none; /* pass clicks through to buttons underneath */ } - .studio-selector-button { display: flex; position: relative; @@ -102,6 +101,7 @@ height: 2.5rem; box-sizing: border-box; justify-content: space-between; + transition: all .5s; } .studio-selector-button-text { @@ -164,30 +164,67 @@ background-color: $ui-blue; } -.studio-status-icon-plus-img { - width: 1.4rem; - height: 1.4rem; +.studio-status-icon-plus-img, .studio-status-icon-checkmark-img, .studio-status-icon-spinner { + width: 1.4rem; + height: 1.4rem; + transform-origin: center; + animation-direction: normal; } -.studio-status-icon--img { - width: 1.4rem; - height: 1.4rem; +.studio-status-icon-with-animation { + animation-duration: .25s; + animation-name: bump; + animation-iteration-count: 1; + animation-timing-function: cubic-bezier(0.3, -3, 0.6, 3); } -.action-button-text .spinner-smooth { - margin: .2125rem auto; - width: 1.875rem; - height: 1rem; +.studio-status-icon-spinner { + animation-name: bump, spin; + -webkit-animation-name: bump, spin; + animation-duration: .25s, .5s; + -webkit-animation-duration: .25s, .5s; + animation-iteration-count: 1, infinite; + -webkit-animation-iteration-count: 1, infinite; + animation-delay: 0s, .25s; + -webkit-animation-delay: 0s, .25s; + animation-timing-function: cubic-bezier(0.3, -3, 0.6, 3), ease-in-out; + -webkit-animation-timing-function: cubic-bezier(0.3, -3, 0.6, 3), ease-in-out; } -.studio-status-icon .spinner-smooth { - position: unset; /* don't understand why neither relative nor absolute work */ +@keyframes intro { + 0% { + transform: scale(0); + -webkit-transform: scale(0); + opacity: 0; + } + 100% { + transform: scale(1); + -webkit-transform: scale(1); + opacity: 1; + } } -.studio-status-icon .spinner-smooth .circle { - /* overlay spinner on circle */ - position: absolute; - margin: .1875rem; /* stay within boundaries of circle */ - width: 75%; /* stay within boundaries of circle */ - height: 75%; /* stay within boundaries of circle */ +@keyframes bump { + 0% { + transform: scale(0); + -webkit-transform: scale(0); + opacity: 0; + } + 100% { + transform: scale(1); + -webkit-transform: scale(1); + opacity: 1; + } +} + +@keyframes spin { + 0% { + transform: rotate(0); + -webkit-transform: rotate(0); + } + + 100% { + transform: rotate(359deg); + -webkit-transform: rotate(359deg); + } } diff --git a/src/components/modal/addtostudio/studio-button.jsx b/src/components/modal/addtostudio/studio-button.jsx index 3a19ac5de..05d1af17b 100644 --- a/src/components/modal/addtostudio/studio-button.jsx +++ b/src/components/modal/addtostudio/studio-button.jsx @@ -1,7 +1,7 @@ const PropTypes = require('prop-types'); const React = require('react'); const classNames = require('classnames'); -const Spinner = require('../../spinner/spinner.jsx'); +const AnimateHOC = require('./animate-hoc'); require('./modal.scss'); @@ -10,19 +10,33 @@ const StudioButton = ({ id, includesProject, title, - onToggleStudio + onToggleStudio, + wasClicked }) => { const checkmark = ( checkmark-icon ); + const spinner = ( + loading animation + ); const plus = ( plus-icon ); @@ -45,16 +59,16 @@ const StudioButton = ({ )} title={title} > - {title} + {title}{wasClicked}
    {(hasRequestOutstanding ? - () : + spinner : (includesProject ? checkmark : plus))}
    @@ -66,7 +80,8 @@ StudioButton.propTypes = { id: PropTypes.number, includesProject: PropTypes.bool, onToggleStudio: PropTypes.func, - title: PropTypes.string + title: PropTypes.string, + wasClicked: PropTypes.bool }; -module.exports = StudioButton; +module.exports = AnimateHOC(StudioButton); From ab4f8a09ceddf2093305c79ed6e1ebae0c1cb97f Mon Sep 17 00:00:00 2001 From: Linda Date: Fri, 7 Sep 2018 16:11:37 -0400 Subject: [PATCH 39/60] the animation now works --- .../modal/addtostudio/animate-hoc.jsx | 36 +++++++++++++------ src/components/modal/addtostudio/modal.scss | 4 +-- .../modal/addtostudio/presentation.jsx | 2 +- .../modal/addtostudio/studio-button.jsx | 17 ++++----- src/views/preview/preview.jsx | 4 +-- 5 files changed, 39 insertions(+), 24 deletions(-) diff --git a/src/components/modal/addtostudio/animate-hoc.jsx b/src/components/modal/addtostudio/animate-hoc.jsx index 02f436f8c..2dc77afdc 100644 --- a/src/components/modal/addtostudio/animate-hoc.jsx +++ b/src/components/modal/addtostudio/animate-hoc.jsx @@ -7,28 +7,42 @@ const PropTypes = require('prop-types'); * @return {React.Component} a wrapped studio button component */ -const AnimateHOC = ({ - Component -}) => { +const AnimateHOC = Component => { class WrappedComponent extends React.Component { - constructor(props) { + constructor (props) { super(props); - let wasClicked = false; + + this.state = { + wasClicked: false + }; + + this.handleClick = this.handleClick.bind(this); } - onClick () { - this.wasClicked = true; // BUT PROPS ARE READONLY? + handleClick () { + if (this.state.wasClicked) { + this.props.onClick(this.props.id); + } else { + this.setState({ + wasClicked: true + }, () => this.props.onClick(this.props.id)); + } } render () { + const {wasClicked} = this.state; return (); } } + WrappedComponent.propTypes = { + id: PropTypes.number, + onClick: PropTypes.func + }; + return WrappedComponent; }; -AnimateHOC.propTypes = { - Component: PropTypes.element -}; +module.exports = AnimateHOC; diff --git a/src/components/modal/addtostudio/modal.scss b/src/components/modal/addtostudio/modal.scss index f4914d45b..ee45d644c 100644 --- a/src/components/modal/addtostudio/modal.scss +++ b/src/components/modal/addtostudio/modal.scss @@ -179,8 +179,8 @@ } .studio-status-icon-spinner { - animation-name: bump, spin; - -webkit-animation-name: bump, spin; + animation-name: intro, spin; + -webkit-animation-name: intro, spin; animation-duration: .25s, .5s; -webkit-animation-duration: .25s, .5s; animation-iteration-count: 1, infinite; diff --git a/src/components/modal/addtostudio/presentation.jsx b/src/components/modal/addtostudio/presentation.jsx index 29e8eedcc..79d405662 100644 --- a/src/components/modal/addtostudio/presentation.jsx +++ b/src/components/modal/addtostudio/presentation.jsx @@ -31,7 +31,7 @@ const AddToStudioModalPresentation = ({ includesProject={studio.includesProject} key={studio.id} title={studio.title} - onToggleStudio={onToggleStudio} + onClick={onToggleStudio} /> )); diff --git a/src/components/modal/addtostudio/studio-button.jsx b/src/components/modal/addtostudio/studio-button.jsx index 05d1af17b..aab9659f3 100644 --- a/src/components/modal/addtostudio/studio-button.jsx +++ b/src/components/modal/addtostudio/studio-button.jsx @@ -1,7 +1,8 @@ const PropTypes = require('prop-types'); const React = require('react'); const classNames = require('classnames'); -const AnimateHOC = require('./animate-hoc'); + +const AnimateHOC = require('./animate-hoc.jsx'); require('./modal.scss'); @@ -10,15 +11,15 @@ const StudioButton = ({ id, includesProject, title, - onToggleStudio, + onClick, wasClicked }) => { const checkmark = ( checkmark-icon @@ -34,8 +35,8 @@ const StudioButton = ({ plus-icon @@ -49,7 +50,7 @@ const StudioButton = ({ includesProject && !hasRequestOutstanding} )} data-id={id} - onClick={onToggleStudio} + onClick={onClick} >
    Date: Fri, 7 Sep 2018 16:19:49 -0400 Subject: [PATCH 40/60] added comments and improved spin animation a little --- src/components/modal/addtostudio/animate-hoc.jsx | 10 +++++++--- src/components/modal/addtostudio/modal.scss | 9 +++++++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/components/modal/addtostudio/animate-hoc.jsx b/src/components/modal/addtostudio/animate-hoc.jsx index 2dc77afdc..6706b6a2f 100644 --- a/src/components/modal/addtostudio/animate-hoc.jsx +++ b/src/components/modal/addtostudio/animate-hoc.jsx @@ -3,6 +3,10 @@ const PropTypes = require('prop-types'); /** * Higher-order component for building an animated studio button + * it is used to decorate the onToggleStudio function with noticing + * when the button has first been clicked. + * This is needed so the buttons don't play the animation when they are + * first rendered but when they are first clicked. * @param {React.Component} Component a studio button component * @return {React.Component} a wrapped studio button component */ @@ -19,12 +23,12 @@ const AnimateHOC = Component => { this.handleClick = this.handleClick.bind(this); } handleClick () { - if (this.state.wasClicked) { + if (this.state.wasClicked) { // if the button has been clicked before this.props.onClick(this.props.id); } else { - this.setState({ + this.setState({ // else tell the state that the button has been clicked wasClicked: true - }, () => this.props.onClick(this.props.id)); + }, () => this.props.onClick(this.props.id)); // callback after state has been updated } } render () { diff --git a/src/components/modal/addtostudio/modal.scss b/src/components/modal/addtostudio/modal.scss index ee45d644c..d886dc572 100644 --- a/src/components/modal/addtostudio/modal.scss +++ b/src/components/modal/addtostudio/modal.scss @@ -179,6 +179,8 @@ } .studio-status-icon-spinner { + /* This class can be used on an icon that should spin. + It first plays the intro animation, then spins forever. */ animation-name: intro, spin; -webkit-animation-name: intro, spin; animation-duration: .25s, .5s; @@ -187,8 +189,8 @@ -webkit-animation-iteration-count: 1, infinite; animation-delay: 0s, .25s; -webkit-animation-delay: 0s, .25s; - animation-timing-function: cubic-bezier(0.3, -3, 0.6, 3), ease-in-out; - -webkit-animation-timing-function: cubic-bezier(0.3, -3, 0.6, 3), ease-in-out; + animation-timing-function: cubic-bezier(0.3, -3, 0.6, 3), linear; + -webkit-animation-timing-function: cubic-bezier(0.3, -3, 0.6, 3), linear; } @keyframes intro { @@ -204,6 +206,9 @@ } } +/* intro and bump look the same but for some reason, +I need two keyframes and if I don't make two separate ones the +animations don't get called. */ @keyframes bump { 0% { transform: scale(0); From 7313f265303768a0175931ad9648dc376f9d4dcb Mon Sep 17 00:00:00 2001 From: Linda Date: Fri, 7 Sep 2018 16:45:17 -0400 Subject: [PATCH 41/60] fixed linting errors --- src/components/modal/addtostudio/modal.scss | 91 +++++++++++---------- 1 file changed, 47 insertions(+), 44 deletions(-) diff --git a/src/components/modal/addtostudio/modal.scss b/src/components/modal/addtostudio/modal.scss index d886dc572..a4db308ab 100644 --- a/src/components/modal/addtostudio/modal.scss +++ b/src/components/modal/addtostudio/modal.scss @@ -92,6 +92,7 @@ .studio-selector-button { display: flex; position: relative; + transition: all .5s; margin: .21875rem .21875rem; border-radius: .5rem; background-color: $ui-white; @@ -101,7 +102,7 @@ height: 2.5rem; box-sizing: border-box; justify-content: space-between; - transition: all .5s; + } .studio-selector-button-text { @@ -164,72 +165,74 @@ background-color: $ui-blue; } -.studio-status-icon-plus-img, .studio-status-icon-checkmark-img, .studio-status-icon-spinner { - width: 1.4rem; - height: 1.4rem; - transform-origin: center; - animation-direction: normal; +.studio-status-icon-plus-img, +.studio-status-icon-checkmark-img, +.studio-status-icon-spinner { + animation-direction: normal; + width: 1.4rem; + height: 1.4rem; + transform-origin: center; } .studio-status-icon-with-animation { - animation-duration: .25s; - animation-name: bump; - animation-iteration-count: 1; - animation-timing-function: cubic-bezier(0.3, -3, 0.6, 3); + animation-name: bump; + animation-duration: .25s; + animation-timing-function: cubic-bezier(.3, -3, .6, 3); + animation-iteration-count: 1; } .studio-status-icon-spinner { /* This class can be used on an icon that should spin. It first plays the intro animation, then spins forever. */ animation-name: intro, spin; - -webkit-animation-name: intro, spin; animation-duration: .25s, .5s; - -webkit-animation-duration: .25s, .5s; - animation-iteration-count: 1, infinite; - -webkit-animation-iteration-count: 1, infinite; + animation-timing-function: cubic-bezier(.3, -3, .6, 3), linear; animation-delay: 0s, .25s; + animation-iteration-count: 1, infinite; + -webkit-animation-name: intro, spin; + -webkit-animation-duration: .25s, .5s; + -webkit-animation-iteration-count: 1, infinite; -webkit-animation-delay: 0s, .25s; - animation-timing-function: cubic-bezier(0.3, -3, 0.6, 3), linear; - -webkit-animation-timing-function: cubic-bezier(0.3, -3, 0.6, 3), linear; + -webkit-animation-timing-function: cubic-bezier(.3, -3, .6, 3), linear; } @keyframes intro { - 0% { - transform: scale(0); - -webkit-transform: scale(0); - opacity: 0; - } - 100% { - transform: scale(1); - -webkit-transform: scale(1); - opacity: 1; - } + 0% { + transform: scale(0); + opacity: 0; + -webkit-transform: scale(0); + } + 100% { + transform: scale(1); + opacity: 1; + -webkit-transform: scale(1); + } } /* intro and bump look the same but for some reason, I need two keyframes and if I don't make two separate ones the animations don't get called. */ @keyframes bump { - 0% { - transform: scale(0); - -webkit-transform: scale(0); - opacity: 0; - } - 100% { - transform: scale(1); - -webkit-transform: scale(1); - opacity: 1; - } + 0% { + transform: scale(0); + opacity: 0; + -webkit-transform: scale(0); + } + 100% { + transform: scale(1); + opacity: 1; + -webkit-transform: scale(1); + } } @keyframes spin { - 0% { - transform: rotate(0); - -webkit-transform: rotate(0); - } + 0% { + transform: rotate(0); + -webkit-transform: rotate(0); + } - 100% { - transform: rotate(359deg); - -webkit-transform: rotate(359deg); - } + 100% { + transform: rotate(359deg); + -webkit-transform: rotate(359deg); + } } From 1cee3c68fccfede85d7e4bd1f9895bb20e5293a6 Mon Sep 17 00:00:00 2001 From: Linda Date: Tue, 11 Sep 2018 17:18:09 -0400 Subject: [PATCH 42/60] removed some leftovers --- src/components/modal/addtostudio/animate-hoc.jsx | 10 +++------- src/components/modal/addtostudio/studio-button.jsx | 5 +---- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/components/modal/addtostudio/animate-hoc.jsx b/src/components/modal/addtostudio/animate-hoc.jsx index 6706b6a2f..f9454ae5d 100644 --- a/src/components/modal/addtostudio/animate-hoc.jsx +++ b/src/components/modal/addtostudio/animate-hoc.jsx @@ -23,13 +23,9 @@ const AnimateHOC = Component => { this.handleClick = this.handleClick.bind(this); } handleClick () { - if (this.state.wasClicked) { // if the button has been clicked before - this.props.onClick(this.props.id); - } else { - this.setState({ // else tell the state that the button has been clicked - wasClicked: true - }, () => this.props.onClick(this.props.id)); // callback after state has been updated - } + this.setState({ // else tell the state that the button has been clicked + wasClicked: true + }, () => this.props.onClick(this.props.id)); // callback after state has been updated } render () { const {wasClicked} = this.state; diff --git a/src/components/modal/addtostudio/studio-button.jsx b/src/components/modal/addtostudio/studio-button.jsx index aab9659f3..6b86afecb 100644 --- a/src/components/modal/addtostudio/studio-button.jsx +++ b/src/components/modal/addtostudio/studio-button.jsx @@ -8,7 +8,6 @@ require('./modal.scss'); const StudioButton = ({ hasRequestOutstanding, - id, includesProject, title, onClick, @@ -49,7 +48,6 @@ const StudioButton = ({ {'studio-selector-button-selected': includesProject && !hasRequestOutstanding} )} - data-id={id} onClick={onClick} >
    - {title}{wasClicked} + {title}
    Date: Wed, 12 Sep 2018 14:54:15 -0400 Subject: [PATCH 43/60] replaced old spinner with new svg to work everywhere where spinner is used --- src/components/login/login.jsx | 5 +- src/components/login/login.scss | 2 +- src/components/modal/addtostudio/modal.scss | 46 +----- .../modal/addtostudio/presentation.jsx | 2 +- .../modal/addtostudio/studio-button.jsx | 9 +- src/components/modal/report/modal.jsx | 2 +- src/components/spinner/spinner.jsx | 33 ++--- src/components/spinner/spinner.scss | 140 +++++------------- src/views/components/components.jsx | 6 +- .../studentcompleteregistration.jsx | 4 +- static/svgs/modal/spinner-blue.svg | 10 ++ .../svgs/modal/spinner-transparent-gray.svg | 10 ++ static/svgs/modal/spinner-white.svg | 10 ++ static/svgs/modal/spinner.svg | 1 - 14 files changed, 94 insertions(+), 186 deletions(-) create mode 100644 static/svgs/modal/spinner-blue.svg create mode 100644 static/svgs/modal/spinner-transparent-gray.svg create mode 100644 static/svgs/modal/spinner-white.svg delete mode 100644 static/svgs/modal/spinner.svg diff --git a/src/components/login/login.jsx b/src/components/login/login.jsx index 58586e5e5..2f4180398 100644 --- a/src/components/login/login.jsx +++ b/src/components/login/login.jsx @@ -75,7 +75,10 @@ class Login extends React.Component { key="submitButton" type="submit" > - + ] : [ diff --git a/src/components/modal/addtostudio/studio-button.jsx b/src/components/modal/addtostudio/studio-button.jsx index 6b86afecb..151e246fc 100644 --- a/src/components/modal/addtostudio/studio-button.jsx +++ b/src/components/modal/addtostudio/studio-button.jsx @@ -2,6 +2,7 @@ const PropTypes = require('prop-types'); const React = require('react'); const classNames = require('classnames'); +const Spinner = require('../../spinner/spinner.jsx'); const AnimateHOC = require('./animate-hoc.jsx'); require('./modal.scss'); @@ -23,13 +24,7 @@ const StudioButton = ({ src="/svgs/modal/confirm.svg" /> ); - const spinner = ( - loading animation - ); + const spinner = ; const plus = ( plus-icon {isWaiting ? (
    - +
    ) : ( diff --git a/src/components/spinner/spinner.jsx b/src/components/spinner/spinner.jsx index 694f5a18e..6d207e200 100644 --- a/src/components/spinner/spinner.jsx +++ b/src/components/spinner/spinner.jsx @@ -1,29 +1,26 @@ -const range = require('lodash.range'); -const PropTypes = require('prop-types'); const React = require('react'); +const PropTypes = require('prop-types'); +const classNames = require('classnames'); require('./spinner.scss'); // Adapted from http://tobiasahlin.com/spinkit/ -const Spinner = ({ - mode -}) => { - const spinnerClassName = (mode === 'smooth' ? 'spinner-smooth' : 'spinner'); - const spinnerDivCount = (mode === 'smooth' ? 24 : 12); - return ( -
    - {range(1, spinnerDivCount + 1).map(id => ( -
    - ))} -
    - ); +// Available colors right now are white, blue and transparent-gray +const Spinner = props => ( + loading animation +); + +Spinner.defaultProps = { + color: 'white' }; Spinner.propTypes = { - mode: PropTypes.string + className: PropTypes.string, + color: PropTypes.string }; module.exports = Spinner; diff --git a/src/components/spinner/spinner.scss b/src/components/spinner/spinner.scss index 2707d02cf..4aba6ad98 100644 --- a/src/components/spinner/spinner.scss +++ b/src/components/spinner/spinner.scss @@ -1,118 +1,44 @@ -@import "../../colors"; - -.spinner { - position: relative; - margin: 0 auto; - width: 20px; - height: 20px; - - .circle { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - - &:before { - display: block; - animation: circleFadeDelay 1.2s infinite ease-in-out both; - margin: 0 auto; - border-radius: 100%; - background-color: $ui-gray; - width: 15%; - height: 15%; - content: ""; - - .white & { - background-color: $ui-blue-dark; - } - } - } - - @for $i from 1 through 12 { - $rotation: 30deg * ($i - 1); - $delay: -1.3s + $i * .1; - - .circle#{$i} { - transform: rotate($rotation); - - &:before { - animation-delay: $delay; - } - } - - } - +.studio-status-icon-spinner { + /* This class can be used on an icon that should spin. + It first plays the intro animation, then spins forever. */ + animation-name: intro, spin; + animation-duration: .25s, .5s; + animation-timing-function: cubic-bezier(.3, -3, .6, 3), linear; + animation-delay: 0s, .25s; + animation-iteration-count: 1, infinite; + animation-direction: normal; + width: 1.4rem; /* standard is 1.4 rem but can be overwritten by parent */ + height: 1.4rem; + -webkit-animation-name: intro, spin; + -webkit-animation-duration: .25s, .5s; + -webkit-animation-iteration-count: 1, infinite; + -webkit-animation-delay: 0s, .25s; + -webkit-animation-timing-function: cubic-bezier(.3, -3, .6, 3), linear; + transform-origin: center; } -@keyframes circleFadeDelay { - 0%, - 39%, +@keyframes intro { + 0% { + transform: scale(0); + opacity: 0; + -webkit-transform: scale(0); + } + 100% { - opacity: 0; - } - - 40% { + transform: scale(1); opacity: 1; + -webkit-transform: scale(1); } } - -/*********************/ -/* type === "smooth" */ -/*********************/ - -.spinner-smooth { - position: relative; - margin: 0 auto; - width: 20px; - height: 20px; - - .circle { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - - &:before { - display: block; - animation: circleFadeDelaySmooth 1.8s infinite ease-in-out both; - margin: 0 auto; - border-radius: 100%; - background-color: $ui-white; - width: 30%; - height: 20%; - content: ""; - - .white & { - background-color: darken($ui-blue, 8%); - } - } +@keyframes spin { + 0% { + transform: rotate(0); + -webkit-transform: rotate(0); } - @for $i from 1 through 24 { - $rotation: 15deg * ($i - 1); - $delay: -1.9s + $i * .075; - - .circle#{$i} { - transform: rotate($rotation); - - &:before { - animation-delay: $delay; - } - } - - } - -} - -@keyframes circleFadeDelaySmooth { - 0%, - 35% { - opacity: 0; - }, - 40% { - opacity: 1; + 100% { + transform: rotate(359deg); + -webkit-transform: rotate(359deg); } } diff --git a/src/views/components/components.jsx b/src/views/components/components.jsx index 3196d93ea..1e01bc4cc 100644 --- a/src/views/components/components.jsx +++ b/src/views/components/components.jsx @@ -35,8 +35,10 @@ const Components = () => ( -

    This is a Spinner

    - +

    This is a blue Spinner

    +

    Colors

    $ui-blue diff --git a/src/views/studentcompleteregistration/studentcompleteregistration.jsx b/src/views/studentcompleteregistration/studentcompleteregistration.jsx index 6724ac87b..c5f3fc104 100644 --- a/src/views/studentcompleteregistration/studentcompleteregistration.jsx +++ b/src/views/studentcompleteregistration/studentcompleteregistration.jsx @@ -75,7 +75,7 @@ class StudentCompleteRegistration extends React.Component { } handleRegister (formData) { this.setState({waiting: true}); - + formData = defaults({}, formData || {}, this.state.formData); const submittedData = { birth_month: formData.user.birth.month, @@ -87,7 +87,7 @@ class StudentCompleteRegistration extends React.Component { if (this.props.must_reset_password) { submittedData.password = formData.user.password; } - + api({ host: '', uri: '/classes/student_update_registration/', diff --git a/static/svgs/modal/spinner-blue.svg b/static/svgs/modal/spinner-blue.svg new file mode 100644 index 000000000..effd69142 --- /dev/null +++ b/static/svgs/modal/spinner-blue.svg @@ -0,0 +1,10 @@ + + + + spinner-blue + Created with Sketch. + + + + + \ No newline at end of file diff --git a/static/svgs/modal/spinner-transparent-gray.svg b/static/svgs/modal/spinner-transparent-gray.svg new file mode 100644 index 000000000..e12923e26 --- /dev/null +++ b/static/svgs/modal/spinner-transparent-gray.svg @@ -0,0 +1,10 @@ + + + + spinner-transparent-gray + Created with Sketch. + + + + + \ No newline at end of file diff --git a/static/svgs/modal/spinner-white.svg b/static/svgs/modal/spinner-white.svg new file mode 100644 index 000000000..547b591dc --- /dev/null +++ b/static/svgs/modal/spinner-white.svg @@ -0,0 +1,10 @@ + + + + spinner-white + Created with Sketch. + + + + + \ No newline at end of file diff --git a/static/svgs/modal/spinner.svg b/static/svgs/modal/spinner.svg deleted file mode 100644 index b6a2b26f1..000000000 --- a/static/svgs/modal/spinner.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file From a60bd65887e8ea39b2b02035cad7829fa64c1b83 Mon Sep 17 00:00:00 2001 From: Linda Date: Wed, 12 Sep 2018 17:28:27 -0400 Subject: [PATCH 44/60] positioning of alert field incomplete --- src/views/preview/preview.scss | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/views/preview/preview.scss b/src/views/preview/preview.scss index 2682d9f66..fd3262a53 100644 --- a/src/views/preview/preview.scss +++ b/src/views/preview/preview.scss @@ -29,7 +29,7 @@ $stage-width: 480px; &.has-error { .validation-message { - transform: translate(22rem, 0); + right: 0; } } @@ -84,9 +84,7 @@ $stage-width: 480px; $arrow-border-width: 1rem; display: block; position: absolute; - top: 0; - left: 0; - margin-left: $arrow-border-width; + margin-top: $arrow-border-width; border: 1px solid $active-gray; border-radius: 5px; background-color: $ui-orange; @@ -96,6 +94,7 @@ $stage-width: 480px; overflow: visible; color: $type-white; font-size: 1rem; + z-index: 1; &:before { display: block; @@ -103,7 +102,7 @@ $stage-width: 480px; top: 1rem; left: -$arrow-border-width / 2; - transform: rotate(45deg); + transform: rotate(135deg); border-bottom: 1px solid $active-gray; border-left: 1px solid $active-gray; @@ -458,7 +457,7 @@ $stage-width: 480px; content: ""; } } - + .studio-button { &:before { background-image: url("/svgs/project/studio-add-white.svg"); From 8a8f3b6da1751ba0770446a55fa9469bf63ef193 Mon Sep 17 00:00:00 2001 From: Linda Date: Thu, 13 Sep 2018 10:39:19 -0400 Subject: [PATCH 45/60] implemented title too long warning design --- src/views/preview/preview.scss | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/views/preview/preview.scss b/src/views/preview/preview.scss index fd3262a53..bff40aa3a 100644 --- a/src/views/preview/preview.scss +++ b/src/views/preview/preview.scss @@ -6,6 +6,12 @@ $player-width: 482px; $player-height: 406px; $stage-width: 480px; +/* screen sizes */ +$small: "screen and (max-width : #{$mobile}-1)"; +$medium: "screen and (min-width : #{$mobile}) and (max-width : #{$tablet}-1)"; +$big: "screen and (min-width : #{$tablet})"; +$medium-and-small: "screen and (max-width : #{$tablet}-1)"; + /* override view padding for share banner */ #view { padding: 0; @@ -73,7 +79,6 @@ $stage-width: 480px; .title { margin-left: 1rem; - /* width: inherit; Inherits the width of whatever this is in. This works well for the preview page and might need to change if used in a different context*/ min-width: 0; text-align: left; font-size: .8rem; @@ -96,11 +101,16 @@ $stage-width: 480px; font-size: 1rem; z-index: 1; + @media #{$medium-and-small} { + width: 100%; + margin-top: calc($arrow-border-width / 2); + } + &:before { display: block; position: absolute; - top: 1rem; - left: -$arrow-border-width / 2; + top: -0.5rem; + left: calc(50% - calc(#{$arrow-border-width} / 2)); transform: rotate(135deg); @@ -113,6 +123,10 @@ $stage-width: 480px; height: $arrow-border-width; content: ""; + + @media #{$medium-and-small} { + display: none; + } } } From 35558bfdbaf66572cbf89e71b0dc3e70e90bb669 Mon Sep 17 00:00:00 2001 From: Linda Date: Thu, 13 Sep 2018 10:49:59 -0400 Subject: [PATCH 46/60] fixed linking problems --- src/views/preview/preview.scss | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/views/preview/preview.scss b/src/views/preview/preview.scss index bff40aa3a..6c6bc556d 100644 --- a/src/views/preview/preview.scss +++ b/src/views/preview/preview.scss @@ -86,9 +86,10 @@ $medium-and-small: "screen and (max-width : #{$tablet}-1)"; } .validation-message { - $arrow-border-width: 1rem; display: block; position: absolute; + z-index: 1; + $arrow-border-width: 1rem; margin-top: $arrow-border-width; border: 1px solid $active-gray; border-radius: 5px; @@ -99,17 +100,16 @@ $medium-and-small: "screen and (max-width : #{$tablet}-1)"; overflow: visible; color: $type-white; font-size: 1rem; - z-index: 1; @media #{$medium-and-small} { - width: 100%; margin-top: calc($arrow-border-width / 2); + width: 100%; } &:before { display: block; position: absolute; - top: -0.5rem; + top: -.5rem; left: calc(50% - calc(#{$arrow-border-width} / 2)); transform: rotate(135deg); From 497aae2a3cb857f57c99302607dc57fedfa9e516 Mon Sep 17 00:00:00 2001 From: Linda Date: Thu, 13 Sep 2018 11:04:14 -0400 Subject: [PATCH 47/60] convention fixes --- src/components/modal/addtostudio/studio-button.jsx | 3 +-- src/components/spinner/spinner.jsx | 12 +++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/components/modal/addtostudio/studio-button.jsx b/src/components/modal/addtostudio/studio-button.jsx index 151e246fc..bfeb35147 100644 --- a/src/components/modal/addtostudio/studio-button.jsx +++ b/src/components/modal/addtostudio/studio-button.jsx @@ -24,7 +24,6 @@ const StudioButton = ({ src="/svgs/modal/confirm.svg" /> ); - const spinner = ; const plus = ( plus-icon {(hasRequestOutstanding ? - spinner : + : (includesProject ? checkmark : plus))}
    diff --git a/src/components/spinner/spinner.jsx b/src/components/spinner/spinner.jsx index 6d207e200..cf723ba6c 100644 --- a/src/components/spinner/spinner.jsx +++ b/src/components/spinner/spinner.jsx @@ -5,12 +5,14 @@ const classNames = require('classnames'); require('./spinner.scss'); // Adapted from http://tobiasahlin.com/spinkit/ -// Available colors right now are white, blue and transparent-gray -const Spinner = props => ( +const Spinner = ({ + className, + color +}) => ( loading animation ); @@ -20,7 +22,7 @@ Spinner.defaultProps = { Spinner.propTypes = { className: PropTypes.string, - color: PropTypes.string + color: PropTypes.oneOf(['white', 'blue', 'transparent-gray']) }; module.exports = Spinner; From 0a50c1fb34dd73172d89c5c932e4317d1c6b3c3d Mon Sep 17 00:00:00 2001 From: Linda Date: Thu, 13 Sep 2018 14:58:00 -0400 Subject: [PATCH 48/60] align notes box and player box on same y pos and align buttons and icons below notifications and player at same y pos --- src/views/preview/preview.scss | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/views/preview/preview.scss b/src/views/preview/preview.scss index 2682d9f66..03938eef4 100644 --- a/src/views/preview/preview.scss +++ b/src/views/preview/preview.scss @@ -192,10 +192,11 @@ $stage-width: 480px; .project-notes { // not 1.5rem because of stage padding margin-left: 1rem; - height: $player-height; + height: calc(#{$player-height} - 1rem); align-items: flex-start; flex: 1; flex-flow: column; + align-self: flex-end; } .share-date { @@ -209,6 +210,7 @@ $stage-width: 480px; .subactions { margin-left: 1.5rem; justify-content: flex-end; + align-items: flex-start; flex: 1; } @@ -384,6 +386,7 @@ $stage-width: 480px; .action-buttons { display: flex; + margin-top: 0; color: $type-white; font-size: .8rem; font-weight: 500; @@ -458,7 +461,7 @@ $stage-width: 480px; content: ""; } } - + .studio-button { &:before { background-image: url("/svgs/project/studio-add-white.svg"); From a9872a14ff65418634935f09101d7e020d6f0346 Mon Sep 17 00:00:00 2001 From: Linda Date: Wed, 19 Sep 2018 15:03:20 -0400 Subject: [PATCH 49/60] fixed problem that occured with remix credits --- src/views/preview/preview.scss | 15 +++++++++++++-- src/views/preview/remix-credit.jsx | 1 + 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/views/preview/preview.scss b/src/views/preview/preview.scss index 03938eef4..82d7fbb03 100644 --- a/src/views/preview/preview.scss +++ b/src/views/preview/preview.scss @@ -192,11 +192,14 @@ $stage-width: 480px; .project-notes { // not 1.5rem because of stage padding margin-left: 1rem; - height: calc(#{$player-height} - 1rem); + height: #{$player-height}; align-items: flex-start; flex: 1; flex-flow: column; - align-self: flex-end; + + > .description-block:first-child { + margin-top: 1rem; + } } .share-date { @@ -230,6 +233,14 @@ $stage-width: 480px; flex-shrink: 1; } + .credit-text { + /* Line clamping is not supported in IE, FF yet */ + display: -webkit-box; + overflow: hidden; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + } + .description-block { display: flex; width: 100%; diff --git a/src/views/preview/remix-credit.jsx b/src/views/preview/remix-credit.jsx index fafeaf4fd..a3557d454 100644 --- a/src/views/preview/remix-credit.jsx +++ b/src/views/preview/remix-credit.jsx @@ -19,6 +19,7 @@ const RemixCredit = props => { {projectInfo.author.username}
    for the original project {projectInfo.title} . From c9b2306827c4111353b95047fe99fcc684e3c9c0 Mon Sep 17 00:00:00 2001 From: Linda Date: Wed, 19 Sep 2018 16:17:14 -0400 Subject: [PATCH 50/60] removed some stuff that is not needed anymore --- src/views/preview/preview.scss | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/views/preview/preview.scss b/src/views/preview/preview.scss index 82d7fbb03..06322c835 100644 --- a/src/views/preview/preview.scss +++ b/src/views/preview/preview.scss @@ -190,9 +190,8 @@ $stage-width: 480px; } .project-notes { - // not 1.5rem because of stage padding margin-left: 1rem; - height: #{$player-height}; + height: $player-height; align-items: flex-start; flex: 1; flex-flow: column; From f721c9591a6cec58d0e713b68e1c7c07aba0ad5b Mon Sep 17 00:00:00 2001 From: Linda Date: Thu, 20 Sep 2018 10:33:00 -0400 Subject: [PATCH 51/60] Ok, css that doesn't work in all browsers is not an option... --- src/views/preview/preview.scss | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/views/preview/preview.scss b/src/views/preview/preview.scss index 06322c835..d19bb3688 100644 --- a/src/views/preview/preview.scss +++ b/src/views/preview/preview.scss @@ -232,14 +232,6 @@ $stage-width: 480px; flex-shrink: 1; } - .credit-text { - /* Line clamping is not supported in IE, FF yet */ - display: -webkit-box; - overflow: hidden; - -webkit-box-orient: vertical; - -webkit-line-clamp: 2; - } - .description-block { display: flex; width: 100%; From 935eb0b15f5f208e677d8c3381966035004a2c5c Mon Sep 17 00:00:00 2001 From: Benjamin Wheeler Date: Mon, 24 Sep 2018 11:04:30 -0400 Subject: [PATCH 52/60] move login/registration functions and view state to session reducer, pass to gui (#2078) * move login/registration functions and view state to session reducer, pass to gui * navigation reducer handles login; gui passed renderLogin function * put back in join class to make smoke tests keep working --- src/components/dropdown/dropdown.scss | 4 +- src/components/intro/intro.jsx | 38 ++- .../login/canceled-deletion-modal.jsx | 60 +++++ src/components/login/connected-login.jsx | 34 +++ src/components/login/login-dropdown.jsx | 50 ++++ src/components/login/login-dropdown.scss | 0 src/components/login/login.jsx | 11 +- src/components/login/login.scss | 28 ++- src/components/modal/base/modal.jsx | 4 +- src/components/navigation/www/accountnav.jsx | 9 +- src/components/navigation/www/navigation.jsx | 236 +++++------------- src/components/navigation/www/navigation.scss | 19 -- src/components/registration/registration.jsx | 30 ++- src/redux/navigation.js | 137 +++++++++- src/redux/reducer.js | 6 +- src/views/preview/preview.jsx | 196 ++++++++------- src/views/search/search.jsx | 6 +- .../studentcompleteregistration.jsx | 30 ++- 18 files changed, 549 insertions(+), 349 deletions(-) create mode 100644 src/components/login/canceled-deletion-modal.jsx create mode 100644 src/components/login/connected-login.jsx create mode 100644 src/components/login/login-dropdown.jsx create mode 100644 src/components/login/login-dropdown.scss diff --git a/src/components/dropdown/dropdown.scss b/src/components/dropdown/dropdown.scss index 6aea2f067..8db2148a7 100644 --- a/src/components/dropdown/dropdown.scss +++ b/src/components/dropdown/dropdown.scss @@ -33,8 +33,8 @@ } input { - // 100% minus border and padding margin-bottom: 12px; + // 100% minus border and padding width: calc(100% - 30px); } @@ -88,7 +88,7 @@ content: ""; } } - + @media only screen and (max-width: $tablet - 1) { min-width: 160px; } diff --git a/src/components/intro/intro.jsx b/src/components/intro/intro.jsx index efe0473a7..243cc4bef 100644 --- a/src/components/intro/intro.jsx +++ b/src/components/intro/intro.jsx @@ -3,7 +3,7 @@ const connect = require('react-redux').connect; const PropTypes = require('prop-types'); const React = require('react'); -const sessionActions = require('../../redux/session.js'); +const navigationActions = require('../../redux/navigation.js'); const IframeModal = require('../modal/iframe/modal.jsx'); const Registration = require('../registration/registration.jsx'); @@ -15,10 +15,7 @@ class Intro extends React.Component { super(props); bindAll(this, [ 'handleShowVideo', - 'handleCloseVideo', - 'handleJoinClick', - 'handleCloseRegistration', - 'handleCompleteRegistration' + 'handleCloseVideo' ]); this.state = { videoOpen: false @@ -30,17 +27,6 @@ class Intro extends React.Component { handleCloseVideo () { this.setState({videoOpen: false}); } - handleJoinClick (e) { - e.preventDefault(); - this.setState({registrationOpen: true}); - } - handleCloseRegistration () { - this.setState({registrationOpen: false}); - } - handleCompleteRegistration () { - this.props.dispatch(sessionActions.refreshSession()); - this.closeRegistration(); - } render () { return (
    @@ -92,7 +78,7 @@ class Intro extends React.Component { Gobo{this.props.messages['intro.itsFree']}
    ({ session: state.session }); -const ConnectedIntro = connect(mapStateToProps)(Intro); +const mapDispatchToProps = dispatch => ({ + handleOpenRegistration: event => { + event.preventDefault(); + dispatch(navigationActions.handleOpenRegistration()); + } +}); + + +const ConnectedIntro = connect( + mapStateToProps, + mapDispatchToProps +)(Intro); module.exports = ConnectedIntro; diff --git a/src/components/login/canceled-deletion-modal.jsx b/src/components/login/canceled-deletion-modal.jsx new file mode 100644 index 000000000..c98028f7d --- /dev/null +++ b/src/components/login/canceled-deletion-modal.jsx @@ -0,0 +1,60 @@ +const React = require('react'); +const connect = require('react-redux').connect; +const FormattedMessage = require('react-intl').FormattedMessage; +const PropTypes = require('prop-types'); +const injectIntl = require('react-intl').injectIntl; +const intlShape = require('react-intl').intlShape; + +const navigationActions = require('../../redux/navigation.js'); +const Modal = require('../modal/base/modal.jsx'); + +const CanceledDeletionModal = ({ + canceledDeletionOpen, + handleCloseCanceledDeletion, + intl +}) => ( + +

    +

    + + {intl.formatMessage({id: 'general.noDeletionLink'})} + + }} + /> +

    +
    +); + +CanceledDeletionModal.propTypes = { + canceledDeletionOpen: PropTypes.bool, + handleCloseCanceledDeletion: PropTypes.func, + intl: intlShape +}; + +const mapStateToProps = state => ({ + canceledDeletionOpen: state.navigation && state.navigation.canceledDeletionOpen +}); + +const mapDispatchToProps = dispatch => ({ + handleCloseCanceledDeletion: () => { + dispatch(navigationActions.setCanceledDeletionOpen(false)); + } +}); + +const ConnectedCanceledDeletionModal = connect( + mapStateToProps, + mapDispatchToProps +)(CanceledDeletionModal); + +module.exports = injectIntl(ConnectedCanceledDeletionModal); diff --git a/src/components/login/connected-login.jsx b/src/components/login/connected-login.jsx new file mode 100644 index 000000000..9f5ec9eba --- /dev/null +++ b/src/components/login/connected-login.jsx @@ -0,0 +1,34 @@ +const PropTypes = require('prop-types'); +const React = require('react'); +const connect = require('react-redux').connect; + +const Login = require('./login.jsx'); + +require('./login-dropdown.scss'); + +const ConnectedLogin = ({ + error, + onLogIn +}) => ( + +); + +ConnectedLogin.propTypes = { + error: PropTypes.string, + onLogIn: PropTypes.func +}; + +const mapStateToProps = state => ({ + error: state.navigation && state.navigation.loginError +}); + +const mapDispatchToProps = () => ({}); + +module.exports = connect( + mapStateToProps, + mapDispatchToProps +)(ConnectedLogin); diff --git a/src/components/login/login-dropdown.jsx b/src/components/login/login-dropdown.jsx new file mode 100644 index 000000000..1f387cf48 --- /dev/null +++ b/src/components/login/login-dropdown.jsx @@ -0,0 +1,50 @@ +const PropTypes = require('prop-types'); +const React = require('react'); +const connect = require('react-redux').connect; + +const navigationActions = require('../../redux/navigation.js'); +const Dropdown = require('../dropdown/dropdown.jsx'); +const ConnectedLogin = require('./connected-login.jsx'); + +require('./login-dropdown.scss'); + +const LoginDropdown = ({ + isOpen, + onClose, + onLogIn +}) => ( + + + +); + +LoginDropdown.propTypes = { + isOpen: PropTypes.bool, + onClose: PropTypes.func, + onLogIn: PropTypes.func +}; + +const mapStateToProps = state => ({ + isOpen: state.navigation && state.navigation.loginOpen +}); + +const mapDispatchToProps = dispatch => ({ + onClose: () => { + dispatch(navigationActions.setLoginOpen(false)); + }, + onLogIn: (formData, callback) => { + dispatch(navigationActions.handleLogIn(formData, callback)); + } +}); + +module.exports = connect( + mapStateToProps, + mapDispatchToProps +)(LoginDropdown); diff --git a/src/components/login/login-dropdown.scss b/src/components/login/login-dropdown.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/components/login/login.jsx b/src/components/login/login.jsx index 2f4180398..116d3fd9a 100644 --- a/src/components/login/login.jsx +++ b/src/components/login/login.jsx @@ -3,8 +3,6 @@ const FormattedMessage = require('react-intl').FormattedMessage; const PropTypes = require('prop-types'); const React = require('react'); -const log = require('../../lib/log.js'); - const Form = require('../forms/form.jsx'); const Input = require('../forms/input.jsx'); const Button = require('../forms/button.jsx'); @@ -24,8 +22,7 @@ class Login extends React.Component { } handleSubmit (formData) { this.setState({waiting: true}); - this.props.onLogIn(formData, err => { - if (err) log.error(err); + this.props.onLogIn(formData, () => { this.setState({waiting: false}); }); } @@ -48,9 +45,6 @@ class Login extends React.Component { key="usernameInput" maxLength="30" name="username" - ref={input => { - this.username = input; - }} type="text" />