From 8e2eef5d5c3121f2971f21fa774c66beb3cfc88c Mon Sep 17 00:00:00 2001
From: Christopher Willis-Ford <cwillisf@media.mit.edu>
Date: Thu, 31 Aug 2017 11:40:05 -0700
Subject: [PATCH] Adjust for scratch-gui / React conventions

---
 src/components/gui/gui.css |  4 ++--
 src/components/gui/gui.jsx | 16 +++++++---------
 src/containers/blocks.jsx  | 16 ++++++++--------
 src/containers/gui.jsx     |  7 +++++++
 4 files changed, 24 insertions(+), 19 deletions(-)

diff --git a/src/components/gui/gui.css b/src/components/gui/gui.css
index 6fee4427f..2c4715479 100644
--- a/src/components/gui/gui.css
+++ b/src/components/gui/gui.css
@@ -99,7 +99,6 @@
 .blocks-wrapper {
     flex-grow: 1;
     position: relative;
-    z-index: 0;
 }
 
 .stage-and-target-wrapper {
@@ -150,7 +149,7 @@
     padding: $space;
 }
 
-.extensionButton {
+.extension-button {
     font-size: 0.55rem;
     font-weight: bold;
     position: absolute;
@@ -158,6 +157,7 @@
     left: 1rem;
     border: 1px solid lightgray;
     background: white;
+    z-index: 50; /** Force extension button above the ScratchBlocks flyout. */
 }
 
 .hidden {
diff --git a/src/components/gui/gui.jsx b/src/components/gui/gui.jsx
index c59b28953..b7d585281 100644
--- a/src/components/gui/gui.jsx
+++ b/src/components/gui/gui.jsx
@@ -34,7 +34,9 @@ const GUIComponent = props => {
     const {
         basePath,
         children,
+        enableExtensions,
         vm,
+        onAddExtensionClick,
         onTabSelect,
         tabIndex,
         ...componentProps
@@ -47,9 +49,6 @@ const GUIComponent = props => {
         );
     }
 
-    const enableExtensions = window.location.search.includes('extensions');
-    const extensionButtonClasses = `${styles.extensionButton} ${enableExtensions ? '' : styles.hidden}`;
-
     const tabClassNames = {
         tabs: styles.tabs,
         tab: classNames(tabStyles.reactTabsTab, styles.tab),
@@ -59,11 +58,6 @@ const GUIComponent = props => {
         tabSelected: classNames(tabStyles.reactTabsTabSelected, styles.isSelected)
     };
 
-    const onAddExtensionClick = () => {
-        /** @TODO open modal for the extension library instead */
-        vm.extensionManager.loadExtensionURL('static/extensions/example-extension.js');
-    };
-
     return (
         <Box
             className={styles.pageWrapper}
@@ -97,7 +91,9 @@ const GUIComponent = props => {
                                     />
                                 </Box>
                                 <IconButton
-                                    className={extensionButtonClasses}
+                                    className={classNames(styles.extensionButton, {
+                                        [styles.hidden]: !enableExtensions
+                                    })}
                                     img={addExtensionIcon}
                                     title={addExtensionMessage}
                                     onClick={onAddExtensionClick}
@@ -140,6 +136,8 @@ const GUIComponent = props => {
 GUIComponent.propTypes = {
     basePath: PropTypes.string,
     children: PropTypes.node,
+    enableExtensions: PropTypes.bool,
+    onAddExtensionClick: PropTypes.func,
     onTabSelect: PropTypes.func,
     tabIndex: PropTypes.number,
     vm: PropTypes.instanceOf(VM).isRequired
diff --git a/src/containers/blocks.jsx b/src/containers/blocks.jsx
index 20b13d3ea..fbd4ecb6d 100644
--- a/src/containers/blocks.jsx
+++ b/src/containers/blocks.jsx
@@ -35,7 +35,7 @@ class Blocks extends React.Component {
             'onScriptGlowOff',
             'onBlockGlowOn',
             'onBlockGlowOff',
-            'onExtensionWasAdded',
+            'handleExtensionAdded',
             'onTargetsUpdate',
             'onVisualReport',
             'onWorkspaceUpdate',
@@ -121,7 +121,7 @@ class Blocks extends React.Component {
         this.props.vm.addListener('VISUAL_REPORT', this.onVisualReport);
         this.props.vm.addListener('workspaceUpdate', this.onWorkspaceUpdate);
         this.props.vm.addListener('targetsUpdate', this.onTargetsUpdate);
-        this.props.vm.addListener('EXTENSION_WAS_ADDED', this.onExtensionWasAdded);
+        this.props.vm.addListener('EXTENSION_ADDED', this.handleExtensionAdded);
     }
     detachVM () {
         this.props.vm.removeListener('SCRIPT_GLOW_ON', this.onScriptGlowOn);
@@ -131,7 +131,7 @@ class Blocks extends React.Component {
         this.props.vm.removeListener('VISUAL_REPORT', this.onVisualReport);
         this.props.vm.removeListener('workspaceUpdate', this.onWorkspaceUpdate);
         this.props.vm.removeListener('targetsUpdate', this.onTargetsUpdate);
-        this.props.vm.removeListener('EXTENSION_WAS_ADDED', this.onExtensionWasAdded);
+        this.props.vm.removeListener('EXTENSION_ADDED', this.handleExtensionAdded);
     }
     updateToolboxBlockValue (id, value) {
         const block = this.workspace
@@ -199,11 +199,11 @@ class Blocks extends React.Component {
             this.workspace.resize();
         }
     }
-    onExtensionWasAdded (blocksInfo) {
+    handleExtensionAdded (blocksInfo) {
         this.ScratchBlocks.defineBlocksWithJsonArray(blocksInfo.map(blockInfo => blockInfo.json));
         const dynamicBlocksXML = this.props.vm.runtime.getBlocksXML();
         const toolboxXML = makeToolboxXML(dynamicBlocksXML);
-        this.props.sendToolboxUpdate(toolboxXML);
+        this.props.onExtensionAdded(toolboxXML);
     }
     setBlocks (blocks) {
         this.blocks = blocks;
@@ -223,8 +223,8 @@ class Blocks extends React.Component {
             options, // eslint-disable-line no-unused-vars
             vm, // eslint-disable-line no-unused-vars
             isVisible, // eslint-disable-line no-unused-vars
+            onExtensionAdded, // eslint-disable-line no-unused-vars
             toolboxXML, // eslint-disable-line no-unused-vars
-            sendToolboxUpdate, // eslint-disable-line no-unused-vars
             ...props
         } = this.props;
         return (
@@ -249,6 +249,7 @@ class Blocks extends React.Component {
 
 Blocks.propTypes = {
     isVisible: PropTypes.bool,
+    onExtensionAdded: PropTypes.func,
     options: PropTypes.shape({
         media: PropTypes.string,
         zoom: PropTypes.shape({
@@ -270,7 +271,6 @@ Blocks.propTypes = {
         }),
         comments: PropTypes.bool
     }),
-    sendToolboxUpdate: PropTypes.func,
     toolboxXML: PropTypes.string,
     vm: PropTypes.instanceOf(VM).isRequired
 };
@@ -311,7 +311,7 @@ const mapStateToProps = state => ({
 });
 
 const mapDispatchToProps = dispatch => ({
-    sendToolboxUpdate: toolboxXML => {
+    onExtensionAdded: toolboxXML => {
         dispatch(updateToolbox(toolboxXML));
     }
 });
diff --git a/src/containers/gui.jsx b/src/containers/gui.jsx
index c41f7a9a9..0fe10b4d1 100644
--- a/src/containers/gui.jsx
+++ b/src/containers/gui.jsx
@@ -12,6 +12,7 @@ class GUI extends React.Component {
     constructor (props) {
         super(props);
         bindAll(this, [
+            'handleAddExtensionClick',
             'handleTabSelect'
         ]);
         this.state = {tabIndex: 0};
@@ -34,6 +35,10 @@ class GUI extends React.Component {
     handleTabSelect (tabIndex) {
         this.setState({tabIndex});
     }
+    handleAddExtensionClick () {
+        /** @TODO open modal for the extension library instead */
+        this.props.vm.extensionManager.loadExtensionURL('static/extensions/example-extension.js');
+    }
     render () {
         const {
             children,
@@ -43,8 +48,10 @@ class GUI extends React.Component {
         } = this.props;
         return (
             <GUIComponent
+                enableExtensions={window.location.search.includes('extensions')}
                 tabIndex={this.state.tabIndex}
                 vm={vm}
+                onAddExtensionClick={this.handleAddExtensionClick}
                 onTabSelect={this.handleTabSelect}
                 {...componentProps}
             >
-- 
GitLab