Merge pull request #1455 from paulkaplan/extract-tab-state

Move active tab state into a reducer
This commit is contained in:
Paul Kaplan authored and GitHub committed 2018-02-22 15:46:32 -05:00
commit 3564544bc2
4 files changed
+71 -27

No files matched your search

+18 -11
View File
@@ -35,15 +35,18 @@ const messages = defineMessages({
const GUIComponent = props => {
const {
activeTabIndex,
basePath,
blocksTabVisible,
children,
intl,
costumesTabVisible,
feedbackFormVisible,
vm,
previewInfoVisible,
intl,
onExtensionButtonClick,
onTabSelect,
tabIndex,
onActivateTab,
previewInfoVisible,
soundsTabVisible,
vm,
...componentProps
} = props;
if (children) {
@@ -86,9 +89,10 @@ const GUIComponent = props => {
<Tabs
className={tabClassNames.tabs}
forceRenderTabPanel={true} // eslint-disable-line react/jsx-boolean-value
selectedIndex={activeTabIndex}
selectedTabClassName={tabClassNames.tabSelected}
selectedTabPanelClassName={tabClassNames.tabPanelSelected}
onSelect={onTabSelect}
onSelect={onActivateTab}
>
<TabList className={tabClassNames.tabList}>
<Tab className={tabClassNames.tab}>Blocks</Tab>
@@ -99,7 +103,7 @@ const GUIComponent = props => {
<Box className={styles.blocksWrapper}>
<Blocks
grow={1}
isVisible={tabIndex === 0} // Blocks tab
isVisible={blocksTabVisible}
options={{
media: `${basePath}static/blocks-media/`
}}
@@ -121,10 +125,10 @@ const GUIComponent = props => {
</Box>
</TabPanel>
<TabPanel className={tabClassNames.tabPanel}>
{tabIndex === 1 ? <CostumeTab vm={vm} /> : null}
{costumesTabVisible ? <CostumeTab vm={vm} /> : null}
</TabPanel>
<TabPanel className={tabClassNames.tabPanel}>
{tabIndex === 2 ? <SoundTab vm={vm} /> : null}
{soundsTabVisible ? <SoundTab vm={vm} /> : null}
</TabPanel>
</Tabs>
</Box>
@@ -159,14 +163,17 @@ const GUIComponent = props => {
);
};
GUIComponent.propTypes = {
activeTabIndex: PropTypes.number,
basePath: PropTypes.string,
blocksTabVisible: PropTypes.bool,
children: PropTypes.node,
costumesTabVisible: PropTypes.bool,
feedbackFormVisible: PropTypes.bool,
intl: intlShape.isRequired,
onActivateTab: PropTypes.func,
onExtensionButtonClick: PropTypes.func,
onTabSelect: PropTypes.func,
previewInfoVisible: PropTypes.bool,
tabIndex: PropTypes.number,
soundsTabVisible: PropTypes.bool,
vm: PropTypes.instanceOf(VM).isRequired
};
GUIComponent.defaultProps = {
+14 -16
View File
@@ -2,23 +2,21 @@ import AudioEngine from 'scratch-audio';
import PropTypes from 'prop-types';
import React from 'react';
import VM from 'scratch-vm';
import bindAll from 'lodash.bindall';
import {connect} from 'react-redux';
import {openExtensionLibrary} from '../reducers/modals.js';
import {openExtensionLibrary} from '../reducers/modals';
import {
activateTab,
BLOCKS_TAB_INDEX,
COSTUMES_TAB_INDEX,
SOUNDS_TAB_INDEX
} from '../reducers/editor-tab';
import vmListenerHOC from '../lib/vm-listener-hoc.jsx';
import GUIComponent from '../components/gui/gui.jsx';
class GUI extends React.Component {
constructor (props) {
super(props);
bindAll(this, [
'handleTabSelect'
]);
this.state = {tabIndex: 0};
}
componentDidMount () {
this.audioEngine = new AudioEngine();
this.props.vm.attachAudioEngine(this.audioEngine);
@@ -34,9 +32,6 @@ class GUI extends React.Component {
componentWillUnmount () {
this.props.vm.stopAll();
}
handleTabSelect (tabIndex) {
this.setState({tabIndex});
}
render () {
const {
children,
@@ -46,9 +41,7 @@ class GUI extends React.Component {
} = this.props;
return (
<GUIComponent
tabIndex={this.state.tabIndex}
vm={vm}
onTabSelect={this.handleTabSelect}
{...componentProps}
>
{children}
@@ -68,12 +61,17 @@ GUI.propTypes = {
GUI.defaultProps = GUIComponent.defaultProps;
const mapStateToProps = state => ({
activeTabIndex: state.editorTab.activeTabIndex,
blocksTabVisible: state.editorTab.activeTabIndex === BLOCKS_TAB_INDEX,
costumesTabVisible: state.editorTab.activeTabIndex === COSTUMES_TAB_INDEX,
feedbackFormVisible: state.modals.feedbackForm,
previewInfoVisible: state.modals.previewInfo
previewInfoVisible: state.modals.previewInfo,
soundsTabVisible: state.editorTab.activeTabIndex === SOUNDS_TAB_INDEX
});
const mapDispatchToProps = dispatch => ({
onExtensionButtonClick: () => dispatch(openExtensionLibrary())
onExtensionButtonClick: () => dispatch(openExtensionLibrary()),
onActivateTab: tab => dispatch(activateTab(tab))
});
const ConnectedGUI = connect(
+37
View File
@@ -0,0 +1,37 @@
const ACTIVATE_TAB = 'scratch-gui/navigation/ACTIVATE_TAB';
// Constants use numbers to make it easier to work with react-tabs
const BLOCKS_TAB_INDEX = 0;
const COSTUMES_TAB_INDEX = 1;
const SOUNDS_TAB_INDEX = 2;
const initialState = {
activeTabIndex: BLOCKS_TAB_INDEX
};
const reducer = function (state, action) {
if (typeof state === 'undefined') state = initialState;
switch (action.type) {
case ACTIVATE_TAB:
return Object.assign({}, state, {
activeTabIndex: action.activeTabIndex
});
default:
return state;
}
};
const activateTab = function (tab) {
return {
type: ACTIVATE_TAB,
activeTabIndex: tab
};
};
export {
reducer as default,
activateTab,
BLOCKS_TAB_INDEX,
COSTUMES_TAB_INDEX,
SOUNDS_TAB_INDEX
};
+2
View File
@@ -9,11 +9,13 @@ import targetReducer from './targets';
import toolboxReducer from './toolbox';
import vmReducer from './vm';
import stageSizeReducer from './stage-size';
import editorTabReducer from './editor-tab';
import {ScratchPaintReducer} from 'scratch-paint';
export default combineReducers({
colorPicker: colorPickerReducer,
customProcedures: customProceduresReducer,
editorTab: editorTabReducer,
intl: intlReducer,
stageSize: stageSizeReducer,
modals: modalReducer,