Merge pull request #3431 from chrisgarrity/issue/www2172-integrate-intl
Refactor IntlProvider in GUI to support integration with www
This commit is contained in:
5 files changed
+71
-33
No files matched your search
+12
-3
@@ -4,7 +4,7 @@ import {compose} from 'redux';
|
||||
import {connect} from 'react-redux';
|
||||
import ReactModal from 'react-modal';
|
||||
import VM from 'scratch-vm';
|
||||
import {injectIntl, intlShape} from 'react-intl';
|
||||
import {defineMessages, injectIntl, intlShape} from 'react-intl';
|
||||
|
||||
import ErrorBoundaryHOC from '../lib/error-boundary-hoc.jsx';
|
||||
import {openExtensionLibrary} from '../reducers/modals';
|
||||
@@ -25,14 +25,22 @@ import {
|
||||
} from '../reducers/modals';
|
||||
|
||||
import FontLoaderHOC from '../lib/font-loader-hoc.jsx';
|
||||
import LocalizationHOC from '../lib/localization-hoc.jsx';
|
||||
import ProjectFetcherHOC from '../lib/project-fetcher-hoc.jsx';
|
||||
import ProjectSaverHOC from '../lib/project-saver-hoc.jsx';
|
||||
import vmListenerHOC from '../lib/vm-listener-hoc.jsx';
|
||||
import vmManagerHOC from '../lib/vm-manager-hoc.jsx';
|
||||
import {defaultProjectTitleMessages} from '../reducers/project-title';
|
||||
|
||||
import GUIComponent from '../components/gui/gui.jsx';
|
||||
|
||||
const messages = defineMessages({
|
||||
defaultProjectTitle: {
|
||||
id: 'gui.gui.defaultProjectTitle',
|
||||
description: 'Default title for project',
|
||||
defaultMessage: 'Scratch Project'
|
||||
}
|
||||
});
|
||||
|
||||
class GUI extends React.Component {
|
||||
componentDidMount () {
|
||||
this.setReduxTitle(this.props.projectTitle);
|
||||
@@ -48,7 +56,7 @@ class GUI extends React.Component {
|
||||
setReduxTitle (newTitle) {
|
||||
if (newTitle === null || typeof newTitle === 'undefined') {
|
||||
this.props.onUpdateReduxProjectTitle(
|
||||
this.props.intl.formatMessage(defaultProjectTitleMessages.defaultProjectTitle)
|
||||
this.props.intl.formatMessage(messages.defaultProjectTitle)
|
||||
);
|
||||
} else {
|
||||
this.props.onUpdateReduxProjectTitle(newTitle);
|
||||
@@ -163,6 +171,7 @@ const ConnectedGUI = injectIntl(connect(
|
||||
// the hierarchy of HOC constructor calls clearer here; it has nothing to do with redux's
|
||||
// ability to compose reducers.
|
||||
const WrappedGui = compose(
|
||||
LocalizationHOC,
|
||||
ErrorBoundaryHOC('Top Level App'),
|
||||
FontLoaderHOC,
|
||||
ProjectFetcherHOC,
|
||||
|
||||
@@ -2,7 +2,6 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {Provider} from 'react-redux';
|
||||
import {createStore, combineReducers, compose} from 'redux';
|
||||
import ConnectedIntlProvider from './connected-intl-provider.jsx';
|
||||
|
||||
import localesReducer, {initLocale, localesInitialState} from '../reducers/locales';
|
||||
|
||||
@@ -108,9 +107,7 @@ const AppStateHOC = function (WrappedComponent, localesOnly) {
|
||||
} = this.props;
|
||||
return (
|
||||
<Provider store={this.store}>
|
||||
<ConnectedIntlProvider>
|
||||
<WrappedComponent {...componentProps} />
|
||||
</ConnectedIntlProvider>
|
||||
<WrappedComponent {...componentProps} />
|
||||
</Provider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {connect} from 'react-redux';
|
||||
|
||||
import ConnectedIntlProvider from './connected-intl-provider.jsx';
|
||||
|
||||
/*
|
||||
* Higher Order Component to provide localiztion state. Creates a nested IntlProvider
|
||||
* to handle Gui intl context. The component accepts an onSetLanguage callback that is
|
||||
* called when the locale chagnes.
|
||||
* @param {React.Component} WrappedComponent - component to provide state for
|
||||
* @returns {React.Component} component with intl state provided from redux
|
||||
*/
|
||||
const LocalizationHOC = function (WrappedComponent) {
|
||||
class LocalizationWrapper extends React.Component {
|
||||
componentDidUpdate (prevProps) {
|
||||
if (prevProps.locale !== this.props.locale) {
|
||||
this.props.onSetLanguage(this.props.locale);
|
||||
}
|
||||
}
|
||||
render () {
|
||||
const {
|
||||
locale, // eslint-disable-line no-unused-vars
|
||||
onSetLanguage, // eslint-disable-line no-unused-vars
|
||||
...componentProps
|
||||
} = this.props;
|
||||
return (
|
||||
<ConnectedIntlProvider>
|
||||
<WrappedComponent {...componentProps} />
|
||||
</ConnectedIntlProvider>
|
||||
);
|
||||
}
|
||||
}
|
||||
LocalizationWrapper.propTypes = {
|
||||
locale: PropTypes.string,
|
||||
onSetLanguage: PropTypes.func
|
||||
};
|
||||
|
||||
LocalizationWrapper.defaultProps = {
|
||||
onSetLanguage: () => {}
|
||||
};
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
locale: state.locales.locale
|
||||
});
|
||||
|
||||
const mapDispatchToProps = () => ({});
|
||||
|
||||
return connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(LocalizationWrapper);
|
||||
};
|
||||
|
||||
export default LocalizationHOC;
|
||||
+3
-15
@@ -1,7 +1,5 @@
|
||||
import React from 'react';
|
||||
import bindAll from 'lodash.bindall';
|
||||
import {intlShape, injectIntl} from 'react-intl';
|
||||
import {defaultProjectTitleMessages} from '../reducers/project-title';
|
||||
|
||||
/* Higher Order Component to get and set the project title
|
||||
* @param {React.Component} WrappedComponent component to receive project title related props
|
||||
@@ -15,34 +13,24 @@ const TitledHOC = function (WrappedComponent) {
|
||||
'handleUpdateProjectTitle'
|
||||
]);
|
||||
this.state = {
|
||||
projectTitle: this.props.intl.formatMessage(defaultProjectTitleMessages.defaultProjectTitle)
|
||||
projectTitle: null
|
||||
};
|
||||
}
|
||||
handleUpdateProjectTitle (newTitle) {
|
||||
this.setState({projectTitle: newTitle});
|
||||
}
|
||||
render () {
|
||||
const {
|
||||
/* eslint-disable no-unused-vars */
|
||||
intl,
|
||||
/* eslint-enable no-unused-vars */
|
||||
...componentProps
|
||||
} = this.props;
|
||||
return (
|
||||
<WrappedComponent
|
||||
projectTitle={this.state.projectTitle}
|
||||
onUpdateProjectTitle={this.handleUpdateProjectTitle}
|
||||
{...componentProps}
|
||||
{...this.props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
TitledComponent.propTypes = {
|
||||
intl: intlShape.isRequired
|
||||
};
|
||||
|
||||
return injectIntl(TitledComponent);
|
||||
return TitledComponent;
|
||||
};
|
||||
|
||||
export {
|
||||
|
||||
@@ -1,19 +1,9 @@
|
||||
import {defineMessages} from 'react-intl';
|
||||
|
||||
const SET_PROJECT_TITLE = 'projectTitle/SET_PROJECT_TITLE';
|
||||
|
||||
// we are initializing to a blank string instead of an actual title,
|
||||
// because it would be hard to localize here
|
||||
const initialState = '';
|
||||
|
||||
const defaultProjectTitleMessages = defineMessages({
|
||||
defaultProjectTitle: {
|
||||
id: 'gui.gui.defaultProjectTitle',
|
||||
description: 'Default title for project',
|
||||
defaultMessage: 'Scratch Project'
|
||||
}
|
||||
});
|
||||
|
||||
const reducer = function (state, action) {
|
||||
if (typeof state === 'undefined') state = initialState;
|
||||
switch (action.type) {
|
||||
@@ -31,6 +21,5 @@ const setProjectTitle = title => ({
|
||||
export {
|
||||
reducer as default,
|
||||
initialState as projectTitleInitialState,
|
||||
defaultProjectTitleMessages,
|
||||
setProjectTitle
|
||||
};
|
||||
Reference in new issue
Block a user