Merge pull request #1455 from paulkaplan/extract-tab-state
Move active tab state into a reducer
This commit is contained in:
4 files changed
+71
-27
No files matched your search
+18
-11
@@ -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
@@ -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(
|
||||
|
||||
@@ -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
|
||||
};
|
||||
@@ -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,
|
||||
|
||||
Reference in new issue
Block a user