diff --git a/src/components/connection-modal/connecting-step.jsx b/src/components/connection-modal/connecting-step.jsx index 063e67a826c79f4c9f55548e321d499d8c86d6a3..be378b3fdd54773f4a1bf9989364a930f9faf433 100644 --- a/src/components/connection-modal/connecting-step.jsx +++ b/src/components/connection-modal/connecting-step.jsx @@ -28,11 +28,7 @@ const ConnectingStep = props => ( </Box> <Box className={styles.bottomArea}> <Box className={styles.instructions}> - <FormattedMessage - defaultMessage="Connecting" - description="" - id="gui.connection.connecting" - /> + {props.connectingMessage} </Box> <Dots counter={1} @@ -64,6 +60,7 @@ const ConnectingStep = props => ( ); ConnectingStep.propTypes = { + connectingMessage: PropTypes.node.isRequired, deviceImage: PropTypes.string.isRequired, onDisconnect: PropTypes.func }; diff --git a/src/components/connection-modal/connection-modal.css b/src/components/connection-modal/connection-modal.css index b636b4af9cdb5e1d4c44505a12b62f3b405d7ecb..b8ca0634b32c81d1504f6f6bd915e1f2dc6380ea 100644 --- a/src/components/connection-modal/connection-modal.css +++ b/src/components/connection-modal/connection-modal.css @@ -183,8 +183,41 @@ align-items: center; } +.scratch-link-help { + display: flex; + flex-direction: column; + justify-content: space-around; + height: 100%; + padding: 1rem 0; +} + +.scratch-link-help-step { + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + margin-left: 3rem; +} + .scratch-link-icon { - max-width: 150px; + max-width: 50px; +} + +.help-step-image { + margin-right: 0.5rem; +} + +.help-step-number { + background: $pen-primary; + border-radius: 100%; + display: flex; + justify-content: center; + align-items: center; + color: $ui-white; + font-weight: bold; + margin-right: 0.5rem; + min-width: 2rem; + height: 2rem; } .button-row { @@ -262,7 +295,7 @@ .instructions { text-align: center; - padding: 1rem; + margin-top: 1rem; } .dots-row { @@ -270,7 +303,7 @@ flex-direction: row; justify-content: center; align-items: center; - padding-bottom: 1rem; + margin: 1rem; } .dots-holder { diff --git a/src/components/connection-modal/connection-modal.jsx b/src/components/connection-modal/connection-modal.jsx index 9a77e92f56ebd4cb439f0c12cbf0cc0a7b46d09e..c6566e954db7c3b5de3b32a8de3a2d6439115838 100644 --- a/src/components/connection-modal/connection-modal.jsx +++ b/src/components/connection-modal/connection-modal.jsx @@ -27,6 +27,7 @@ const ConnectionModalComponent = props => ( contentLabel={props.name} headerClassName={styles.header} headerImage={props.smallDeviceImage} + onHelp={props.onHelp} onRequestClose={props.onCancel} > <Box className={styles.body}> @@ -40,8 +41,10 @@ const ConnectionModalComponent = props => ( ); ConnectionModalComponent.propTypes = { + connectingMessage: PropTypes.node, name: PropTypes.node, onCancel: PropTypes.func.isRequired, + onHelp: PropTypes.func.isRequired, phase: PropTypes.oneOf(Object.keys(PHASES)).isRequired, smallDeviceImage: PropTypes.string, title: PropTypes.string.isRequired diff --git a/src/components/connection-modal/error-step.jsx b/src/components/connection-modal/error-step.jsx index 9f491aab988021a8007177959c7d7b762defb053..194e95678fed2fae311e583c35f0a676acc58aa8 100644 --- a/src/components/connection-modal/error-step.jsx +++ b/src/components/connection-modal/error-step.jsx @@ -26,7 +26,7 @@ const ErrorStep = props => ( <FormattedMessage defaultMessage="Oops, looks like something went wrong." description="The device connection process has encountered an error." - id="gui.connection.errorMessage" + id="gui.connection.error.errorMessage" /> </div> <Dots @@ -43,7 +43,9 @@ const ErrorStep = props => ( src={backIcon} /> <FormattedMessage - id="gui.connection.tryagainbutton" + defaultMessage="Try again" + description="Button to initiate trying the device connection again after an error" + id="gui.connection.error.tryagainbutton" /> </button> <button @@ -55,7 +57,9 @@ const ErrorStep = props => ( src={helpIcon} /> <FormattedMessage - id="gui.connection.helpbutton" + defaultMessage="Help" + description="Button to view help content" + id="gui.connection.error.helpbutton" /> </button> </Box> diff --git a/src/components/connection-modal/icons/bluetooth.svg b/src/components/connection-modal/icons/bluetooth.svg new file mode 100644 index 0000000000000000000000000000000000000000..ebec155b4398ed010a30ab4d10ecb4597c52ad8c Binary files /dev/null and b/src/components/connection-modal/icons/bluetooth.svg differ diff --git a/src/components/connection-modal/icons/scratch-link.png b/src/components/connection-modal/icons/scratch-link.png deleted file mode 100644 index af7ceed4baac35730f1b803bc9477aa1b4f208a9..0000000000000000000000000000000000000000 Binary files a/src/components/connection-modal/icons/scratch-link.png and /dev/null differ diff --git a/src/components/connection-modal/icons/scratchlink.svg b/src/components/connection-modal/icons/scratchlink.svg new file mode 100644 index 0000000000000000000000000000000000000000..de2011a5efd5fd213ad0bd269bce6ba9e5d17a93 Binary files /dev/null and b/src/components/connection-modal/icons/scratchlink.svg differ diff --git a/src/components/connection-modal/unavailable-step.jsx b/src/components/connection-modal/unavailable-step.jsx index 2f789cbdb0e1a1d070e0c7e4abbe4d93a6143b18..975a66debe7d0b14b25a87c632c04a494775ac4d 100644 --- a/src/components/connection-modal/unavailable-step.jsx +++ b/src/components/connection-modal/unavailable-step.jsx @@ -6,30 +6,54 @@ import Box from '../box/box.jsx'; import Dots from './dots.jsx'; import helpIcon from './icons/help.svg'; import backIcon from './icons/back.svg'; -import scratchLinkIcon from './icons/scratch-link.png'; +import bluetoothIcon from './icons/bluetooth.svg'; +import scratchLinkIcon from './icons/scratchlink.svg'; import styles from './connection-modal.css'; const UnavailableStep = props => ( <Box className={styles.body}> <Box className={styles.activityArea}> - <Box className={styles.centeredRow}> - <div className={styles.deviceActivity}> - <img - className={styles.scratchLinkIcon} - src={scratchLinkIcon} - /> + <div className={styles.scratchLinkHelp}> + <div className={styles.scratchLinkHelpStep}> + <div className={styles.helpStepNumber}> + {'1'} + </div> + <div className={styles.helpStepImage}> + <img + className={styles.scratchLinkIcon} + src={scratchLinkIcon} + /> + </div> + <div className={styles.helpStepText}> + <FormattedMessage + defaultMessage="Make sure you have Scratch Link installed and running" + description="Message for getting Scratch Link installed" + id="gui.connection.unavailable.installscratchlink" + /> + </div> </div> - </Box> + <div className={styles.scratchLinkHelpStep}> + <div className={styles.helpStepNumber}> + {'2'} + </div> + <div className={styles.helpStepImage}> + <img + className={styles.scratchLinkIcon} + src={bluetoothIcon} + /> + </div> + <div className={styles.helpStepText}> + <FormattedMessage + defaultMessage="Check that Bluetooth is enabled" + description="Message for making sure Bluetooth is enabled" + id="gui.connection.unavailable.enablebluetooth" + /> + </div> + </div> + </div> </Box> <Box className={styles.bottomArea}> - <div className={styles.instructions}> - <FormattedMessage - defaultMessage="Please start Scratch Link and turn on Bluetooth." - description="Scratch link is not installed message" - id="gui.connection.unavailableMessage" - /> - </div> <Dots error total={3} @@ -46,7 +70,7 @@ const UnavailableStep = props => ( <FormattedMessage defaultMessage="Try again" description="Button to initiate trying the device connection again after an error" - id="gui.connection.tryagainbutton" + id="gui.connection.unavailable.tryagainbutton" /> </button> <button @@ -60,7 +84,7 @@ const UnavailableStep = props => ( <FormattedMessage defaultMessage="Help" description="Button to view help content" - id="gui.connection.helpbutton" + id="gui.connection.unavailable.helpbutton" /> </button> </Box> diff --git a/src/components/modal/modal.css b/src/components/modal/modal.css index 9a5a035a7de18edba2d6d5343fdc4fa97f213878..8bf2b6cb8fab403f28a867468b7d437c5f4de684 100644 --- a/src/components/modal/modal.css +++ b/src/components/modal/modal.css @@ -122,3 +122,14 @@ $sides: 20rem; font-weight: normal; padding-left: 0; } + +.header-item-help { + padding: 0; + margin-right: -4.75rem; +} + +.help-button { + font-weight: normal; + padding-right: 0; + font-size: 0.75rem; +} diff --git a/src/components/modal/modal.jsx b/src/components/modal/modal.jsx index 940af75586f59e05291f9970b5bf972f353ccdb3..acce21993d86b23137104f5f7bddc1215c1d26bf 100644 --- a/src/components/modal/modal.jsx +++ b/src/components/modal/modal.jsx @@ -9,6 +9,7 @@ import Button from '../button/button.jsx'; import CloseButton from '../close-button/close-button.jsx'; import backIcon from '../../lib/assets/icon--back.svg'; +import helpIcon from '../../lib/assets/icon--help.svg'; import styles from './modal.css'; @@ -27,6 +28,26 @@ const ModalComponent = props => ( grow={1} > <div className={classNames(styles.header, props.headerClassName)}> + {props.onHelp ? ( + <div + className={classNames( + styles.headerItem, + styles.headerItemHelp + )} + > + <Button + className={styles.helpButton} + iconSrc={helpIcon} + onClick={props.onHelp} + > + <FormattedMessage + defaultMessage="Help" + description="Help button in modal" + id="gui.modal.help" + /> + </Button> + </div> + ) : null} <div className={classNames( styles.headerItem, @@ -82,6 +103,7 @@ ModalComponent.propTypes = { fullScreen: PropTypes.bool, headerClassName: PropTypes.string, headerImage: PropTypes.string, + onHelp: PropTypes.func, onRequestClose: PropTypes.func }; diff --git a/src/containers/blocks.jsx b/src/containers/blocks.jsx index 1de665e33422b5372322ec02018912b18fd8da29..56f2fa5d5fc7979f9f50fa1b0cdc9268596c7d7d 100644 --- a/src/containers/blocks.jsx +++ b/src/containers/blocks.jsx @@ -355,7 +355,9 @@ class Blocks extends React.Component { extensionId: extensionId, deviceImage: extension.deviceImage, smallDeviceImage: extension.smallDeviceImage, - name: extension.name + name: extension.name, + connectingMessage: extension.connectingMessage, + helpLink: extension.helpLink }}); } } @@ -419,8 +421,10 @@ class Blocks extends React.Component { ) : null} {this.state.connectionModal ? ( <ConnectionModal + connectingMessage={this.state.connectionModal.connectingMessage} deviceImage={this.state.connectionModal.deviceImage} extensionId={this.state.connectionModal.extensionId} + helpLink={this.state.connectionModal.helpLink} name={this.state.connectionModal.name} smallDeviceImage={this.state.connectionModal.smallDeviceImage} vm={vm} diff --git a/src/containers/connection-modal.jsx b/src/containers/connection-modal.jsx index 3b1a68b3adc72942123b1275b18484fa12623067..50862fbd2b31e6e830f756484fcd47e0fcbac0e8 100644 --- a/src/containers/connection-modal.jsx +++ b/src/containers/connection-modal.jsx @@ -12,7 +12,8 @@ class ConnectionModal extends React.Component { 'handleConnected', 'handleConnecting', 'handleDisconnect', - 'handleError' + 'handleError', + 'handleHelp' ]); this.state = { phase: PHASES.scanning @@ -76,11 +77,12 @@ class ConnectionModal extends React.Component { }); } handleHelp () { - // @todo: implement the help button + window.open(this.props.helpLink, '_blank'); } render () { return ( <ConnectionModalComponent + connectingMessage={this.props.connectingMessage} deviceImage={this.props.deviceImage} extensionId={this.props.extensionId} name={this.props.name} @@ -100,8 +102,10 @@ class ConnectionModal extends React.Component { } ConnectionModal.propTypes = { + connectingMessage: PropTypes.node.isRequired, deviceImage: PropTypes.string.isRequired, extensionId: PropTypes.string.isRequired, + helpLink: PropTypes.string.isRequired, name: PropTypes.node.isRequired, onCancel: PropTypes.func.isRequired, onStatusButtonUpdate: PropTypes.func.isRequired, diff --git a/src/lib/assets/icon--help.svg b/src/lib/assets/icon--help.svg new file mode 100644 index 0000000000000000000000000000000000000000..2938e8340ebb54dd699f80eaf48794bd383a96a4 Binary files /dev/null and b/src/lib/assets/icon--help.svg differ diff --git a/src/lib/libraries/extensions/index.jsx b/src/lib/libraries/extensions/index.jsx index 1ef3bd706d3ece154bb8b3a7a4872b2e9af60c90..79de349873ad154fc91213d1d4bca6529808a4fe 100644 --- a/src/lib/libraries/extensions/index.jsx +++ b/src/lib/libraries/extensions/index.jsx @@ -106,7 +106,15 @@ export default [ disabled: true, launchDeviceConnectionFlow: true, deviceImage: microbitDeviceImage, - smallDeviceImage: microbitMenuImage + smallDeviceImage: microbitMenuImage, + connectingMessage: ( + <FormattedMessage + defaultMessage="Connecting" + description="Message to help people connect to their micro:bit." + id="gui.extension.microbit.connectingMessage" + /> + ), + helpLink: 'https://scratch.mit.edu/microbit' }, { name: 'LEGO MINDSTORMS EV3', @@ -123,7 +131,15 @@ export default [ disabled: true, launchDeviceConnectionFlow: true, deviceImage: ev3DeviceImage, - smallDeviceImage: ev3MenuImage + smallDeviceImage: ev3MenuImage, + connectingMessage: ( + <FormattedMessage + defaultMessage="Connecting. Make sure the pin on your EV3 is set to 1234." + description="Message to help people connect to their EV3. Must note the PIN should be 1234." + id="gui.extension.ev3.connectingMessage" + /> + ), + helpLink: 'https://scratch.mit.edu/ev3' }, { name: 'LEGO WeDo 2.0',