move project title management into titled hoc

This commit is contained in:
Ben Wheeler committed 2019-10-17 13:26:33 -04:00
1 parent 91e2fc92f3
commit b63ac51fb1
2 files changed
+90 -44

No files matched your search

+5 -36
View File
@@ -4,15 +4,13 @@ import {compose} from 'redux';
import {connect} from 'react-redux';
import ReactModal from 'react-modal';
import VM from 'scratch-vm';
import {defineMessages, injectIntl, intlShape} from 'react-intl';
import {injectIntl, intlShape} from 'react-intl';
import ErrorBoundaryHOC from '../lib/error-boundary-hoc.jsx';
import {
getIsError,
getIsShowingProject,
getIsShowingWithoutId
getIsShowingProject
} from '../reducers/project-state';
import {setProjectTitle} from '../reducers/project-title';
import {
activateTab,
BLOCKS_TAB_INDEX,
@@ -30,6 +28,7 @@ import {
import FontLoaderHOC from '../lib/font-loader-hoc.jsx';
import LocalizationHOC from '../lib/localization-hoc.jsx';
import ProjectFetcherHOC from '../lib/project-fetcher-hoc.jsx';
import TitledHOC from '../lib/titled-hoc.jsx';
import ProjectSaverHOC from '../lib/project-saver-hoc.jsx';
import QueryParserHOC from '../lib/query-parser-hoc.jsx';
import storage from '../lib/storage';
@@ -40,18 +39,9 @@ import cloudManagerHOC from '../lib/cloud-manager-hoc.jsx';
import GUIComponent from '../components/gui/gui.jsx';
import {setIsScratchDesktop} from '../lib/isScratchDesktop.js';
const messages = defineMessages({
defaultProjectTitle: {
id: 'gui.gui.defaultProjectTitle',
description: 'Default title for project',
defaultMessage: 'Scratch Project'
}
});
class GUI extends React.Component {
componentDidMount () {
setIsScratchDesktop(this.props.isScratchDesktop);
this.setReduxTitle(this.props.projectTitle);
this.props.onStorageInit(storage);
this.props.onVmInit(this.props.vm);
}
@@ -59,26 +49,11 @@ class GUI extends React.Component {
if (this.props.projectId !== prevProps.projectId && this.props.projectId !== null) {
this.props.onUpdateProjectId(this.props.projectId);
}
if (this.props.projectTitle !== prevProps.projectTitle) {
this.setReduxTitle(this.props.projectTitle);
}
if (this.props.isShowingProject && !prevProps.isShowingProject) {
// this only notifies container when a project changes from not yet loaded to loaded
// At this time the project view in www doesn't need to know when a project is unloaded
this.props.onProjectLoaded();
}
if (this.props.isShowingWithoutId && !prevProps.isShowingWithoutId) {
this.props.onUpdateProjectTitle(this.props.intl.formatMessage(messages.defaultProjectTitle));
}
}
setReduxTitle (newTitle) {
if (newTitle === null || typeof newTitle === 'undefined') {
this.props.onUpdateReduxProjectTitle(
this.props.intl.formatMessage(messages.defaultProjectTitle)
);
} else {
this.props.onUpdateReduxProjectTitle(newTitle);
}
}
render () {
if (this.props.isError) {
@@ -96,11 +71,9 @@ class GUI extends React.Component {
onProjectLoaded,
onStorageInit,
onUpdateProjectId,
onUpdateReduxProjectTitle,
onVmInit,
projectHost,
projectId,
projectTitle,
/* eslint-enable no-unused-vars */
children,
fetchingProject,
@@ -137,11 +110,9 @@ GUI.propTypes = {
onStorageInit: PropTypes.func,
onUpdateProjectId: PropTypes.func,
onUpdateProjectTitle: PropTypes.func,
onUpdateReduxProjectTitle: PropTypes.func,
onVmInit: PropTypes.func,
projectHost: PropTypes.string,
projectId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
projectTitle: PropTypes.string,
telemetryModalVisible: PropTypes.bool,
vm: PropTypes.instanceOf(VM).isRequired
};
@@ -151,7 +122,6 @@ GUI.defaultProps = {
onStorageInit: storageInstance => storageInstance.addOfficialScratchWebStores(),
onProjectLoaded: () => {},
onUpdateProjectId: () => {},
onUpdateProjectTitle: () => {},
onVmInit: (/* vm */) => {}
};
@@ -172,7 +142,6 @@ const mapStateToProps = state => {
isPlayerOnly: state.scratchGui.mode.isPlayerOnly,
isRtl: state.locales.isRtl,
isShowingProject: getIsShowingProject(loadingState),
isShowingWithoutId: getIsShowingWithoutId(loadingState),
loadingStateVisible: state.scratchGui.modals.loadingProject,
projectId: state.scratchGui.projectState.projectId,
soundsTabVisible: state.scratchGui.editorTab.activeTabIndex === SOUNDS_TAB_INDEX,
@@ -193,8 +162,7 @@ const mapDispatchToProps = dispatch => ({
onActivateSoundsTab: () => dispatch(activateTab(SOUNDS_TAB_INDEX)),
onRequestCloseBackdropLibrary: () => dispatch(closeBackdropLibrary()),
onRequestCloseCostumeLibrary: () => dispatch(closeCostumeLibrary()),
onRequestCloseTelemetryModal: () => dispatch(closeTelemetryModal()),
onUpdateReduxProjectTitle: title => dispatch(setProjectTitle(title))
onRequestCloseTelemetryModal: () => dispatch(closeTelemetryModal())
});
const ConnectedGUI = injectIntl(connect(
@@ -211,6 +179,7 @@ const WrappedGui = compose(
FontLoaderHOC,
QueryParserHOC,
ProjectFetcherHOC,
TitledHOC,
ProjectSaverHOC,
vmListenerHOC,
vmManagerHOC,
+85 -8
View File
@@ -1,5 +1,19 @@
import PropTypes from 'prop-types';
import React from 'react';
import bindAll from 'lodash.bindall';
import {connect} from 'react-redux';
import {defineMessages, injectIntl, intlShape} from 'react-intl';
import {getIsShowingWithoutId} from '../reducers/project-state';
import {setProjectTitle} from '../reducers/project-title';
const messages = defineMessages({
defaultProjectTitle: {
id: 'gui.gui.defaultProjectTitle',
description: 'Default title for project',
defaultMessage: 'Scratch Project'
}
});
/* Higher Order Component to get and set the project title
* @param {React.Component} WrappedComponent component to receive project title related props
@@ -12,26 +26,89 @@ const TitledHOC = function (WrappedComponent) {
bindAll(this, [
'handleUpdateProjectTitle'
]);
this.state = {
projectTitle: null
};
}
componentDidMount () {
this.setReduxTitle(this.props.projectTitle);
}
componentDidUpdate (prevProps) {
if (this.props.projectTitle !== prevProps.projectTitle) {
this.setReduxTitle(this.props.projectTitle);
}
if (this.props.isShowingWithoutId && !prevProps.isShowingWithoutId) {
const defaultProjectTitle = this.titleWithDefault();
this.setReduxTitle(defaultProjectTitle);
this.props.onUpdateProjectTitle(defaultProjectTitle);
}
}
titleWithDefault (title) {
if (title === null || typeof title === 'undefined') {
return this.props.intl.formatMessage(messages.defaultProjectTitle);
}
return title;
}
setReduxTitle (newTitle) {
if (newTitle === null || typeof newTitle === 'undefined') {
this.props.onUpdateReduxProjectTitle(
this.props.intl.formatMessage(messages.defaultProjectTitle)
);
} else {
this.props.onUpdateReduxProjectTitle(newTitle);
}
}
handleUpdateProjectTitle (newTitle) {
this.setState({projectTitle: newTitle});
this.setReduxTitle(newTitle);
this.props.onUpdateProjectTitle(newTitle);
}
render () {
const {
/* eslint-disable no-unused-vars */
intl,
isShowingWithoutId,
// for children, we replace onUpdateProjectTitle with our own
onUpdateProjectTitle,
onUpdateReduxProjectTitle,
// we don't pass projectTitle prop to children -- they must use
// redux value
projectTitle,
/* eslint-enable no-unused-vars */
...componentProps
} = this.props;
return (
<WrappedComponent
canEditTitle
projectTitle={this.state.projectTitle}
onUpdateProjectTitle={this.handleUpdateProjectTitle}
{...this.props}
{...componentProps}
/>
);
}
}
return TitledComponent;
TitledComponent.propTypes = {
intl: intlShape,
isShowingWithoutId: PropTypes.bool,
onUpdateProjectTitle: PropTypes.func,
onUpdateReduxProjectTitle: PropTypes.func,
projectTitle: PropTypes.string
};
TitledComponent.defaultProps = {
onUpdateProjectTitle: () => {}
};
const mapStateToProps = state => {
const loadingState = state.scratchGui.projectState.loadingState;
return {
isShowingWithoutId: getIsShowingWithoutId(loadingState)
};
};
const mapDispatchToProps = dispatch => ({
onUpdateReduxProjectTitle: title => dispatch(setProjectTitle(title))
});
return injectIntl(connect(
mapStateToProps,
mapDispatchToProps,
)(TitledComponent));
};
export {