mirror of
https://github.com/scratchfoundation/scratch-desktop.git
synced 2024-12-23 06:02:30 -05:00
split HOC in two: one inside AppStateHOC, one out
`ScratchDesktopOuterComponent` is now responsible for `showTelemetryModal` which only works if it comes from outside the `AppStateHOC` since it's used in the `AppStateHOC` constructor. The outer component also handles a few static props, like `isScratchDesktop`. `ScratchDesktopInnerComponent` handles everything else, most notably anything that interacts with the state established by `AppStateHOC`.
This commit is contained in:
parent
d8f289f35a
commit
19a47ecde8
1 changed files with 28 additions and 14 deletions
|
@ -7,7 +7,7 @@ import ReactDOM from 'react-dom';
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import {compose} from 'redux';
|
import {compose} from 'redux';
|
||||||
import GUI from 'scratch-gui/src/index';
|
import GUI from 'scratch-gui/src/index';
|
||||||
import VM from 'scratch-vm';
|
import GUIComponent from 'scratch-gui/src/components/gui/gui.jsx';
|
||||||
|
|
||||||
import AppStateHOC from 'scratch-gui/src/lib/app-state-hoc.jsx';
|
import AppStateHOC from 'scratch-gui/src/lib/app-state-hoc.jsx';
|
||||||
import {
|
import {
|
||||||
|
@ -43,8 +43,26 @@ document.body.appendChild(appTarget);
|
||||||
|
|
||||||
GUI.setAppElement(appTarget);
|
GUI.setAppElement(appTarget);
|
||||||
|
|
||||||
const ScratchDesktopHOC = function (WrappedComponent) {
|
const ScratchDesktopOuterHOC = function (WrappedComponent) {
|
||||||
class ScratchDesktopComponent extends React.Component {
|
const ScratchDesktopOuterComponent = function (props) {
|
||||||
|
const shouldShowTelemetryModal = (typeof ipcRenderer.sendSync('getTelemetryDidOptIn') !== 'boolean');
|
||||||
|
|
||||||
|
return (<WrappedComponent
|
||||||
|
canEditTitle
|
||||||
|
canModifyCloudData={false}
|
||||||
|
isScratchDesktop
|
||||||
|
showTelemetryModal={shouldShowTelemetryModal}
|
||||||
|
|
||||||
|
// allow passed-in props to override any of the above
|
||||||
|
{...props}
|
||||||
|
/>);
|
||||||
|
};
|
||||||
|
|
||||||
|
return ScratchDesktopOuterComponent;
|
||||||
|
};
|
||||||
|
|
||||||
|
const ScratchDesktopInnerHOC = function (WrappedComponent) {
|
||||||
|
class ScratchDesktopInnerComponent extends React.Component {
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
super(props);
|
super(props);
|
||||||
bindAll(this, [
|
bindAll(this, [
|
||||||
|
@ -116,15 +134,9 @@ const ScratchDesktopHOC = function (WrappedComponent) {
|
||||||
this.setState({projectTitle: newTitle});
|
this.setState({projectTitle: newTitle});
|
||||||
}
|
}
|
||||||
render () {
|
render () {
|
||||||
const shouldShowTelemetryModal = (typeof ipcRenderer.sendSync('getTelemetryDidOptIn') !== 'boolean');
|
const childProps = omit(this.props, Object.keys(ScratchDesktopInnerComponent.propTypes));
|
||||||
|
|
||||||
const childProps = omit(this.props, Object.keys(ScratchDesktopComponent.propTypes));
|
|
||||||
|
|
||||||
return (<WrappedComponent
|
return (<WrappedComponent
|
||||||
canEditTitle
|
|
||||||
canModifyCloudData={false}
|
|
||||||
isScratchDesktop
|
|
||||||
showTelemetryModal={shouldShowTelemetryModal}
|
|
||||||
onClickLogo={this.handleClickLogo}
|
onClickLogo={this.handleClickLogo}
|
||||||
onProjectTelemetryEvent={this.handleProjectTelemetryEvent}
|
onProjectTelemetryEvent={this.handleProjectTelemetryEvent}
|
||||||
onStorageInit={this.handleStorageInit}
|
onStorageInit={this.handleStorageInit}
|
||||||
|
@ -138,7 +150,7 @@ const ScratchDesktopHOC = function (WrappedComponent) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ScratchDesktopComponent.propTypes = {
|
ScratchDesktopInnerComponent.propTypes = {
|
||||||
loadingState: PropTypes.oneOf(LoadingStates),
|
loadingState: PropTypes.oneOf(LoadingStates),
|
||||||
onFetchedInitialProjectData: PropTypes.func,
|
onFetchedInitialProjectData: PropTypes.func,
|
||||||
onHasInitialProject: PropTypes.func,
|
onHasInitialProject: PropTypes.func,
|
||||||
|
@ -146,7 +158,8 @@ const ScratchDesktopHOC = function (WrappedComponent) {
|
||||||
onLoadingCompleted: PropTypes.func,
|
onLoadingCompleted: PropTypes.func,
|
||||||
onLoadingStarted: PropTypes.func,
|
onLoadingStarted: PropTypes.func,
|
||||||
onRequestNewProject: PropTypes.func,
|
onRequestNewProject: PropTypes.func,
|
||||||
vm: PropTypes.instanceOf(VM).isRequired
|
// using PropTypes.instanceOf(VM) here will cause prop type warnings due to VM mismatch
|
||||||
|
vm: GUIComponent.WrappedComponent.propTypes.vm
|
||||||
};
|
};
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = state => {
|
||||||
const loadingState = state.scratchGui.projectState.loadingState;
|
const loadingState = state.scratchGui.projectState.loadingState;
|
||||||
|
@ -177,15 +190,16 @@ const ScratchDesktopHOC = function (WrappedComponent) {
|
||||||
onRequestNewProject: () => dispatch(requestNewProject(false))
|
onRequestNewProject: () => dispatch(requestNewProject(false))
|
||||||
});
|
});
|
||||||
|
|
||||||
return connect(mapStateToProps, mapDispatchToProps)(ScratchDesktopComponent);
|
return connect(mapStateToProps, mapDispatchToProps)(ScratchDesktopInnerComponent);
|
||||||
};
|
};
|
||||||
|
|
||||||
// note that redux's 'compose' function is just being used as a general utility to make
|
// note that redux's 'compose' function is just being used as a general utility to make
|
||||||
// the hierarchy of HOC constructor calls clearer here; it has nothing to do with redux's
|
// the hierarchy of HOC constructor calls clearer here; it has nothing to do with redux's
|
||||||
// ability to compose reducers.
|
// ability to compose reducers.
|
||||||
const WrappedGui = compose(
|
const WrappedGui = compose(
|
||||||
|
ScratchDesktopOuterHOC,
|
||||||
AppStateHOC,
|
AppStateHOC,
|
||||||
ScratchDesktopHOC
|
ScratchDesktopInnerHOC
|
||||||
)(GUI);
|
)(GUI);
|
||||||
|
|
||||||
ReactDOM.render(<WrappedGui />, appTarget);
|
ReactDOM.render(<WrappedGui />, appTarget);
|
||||||
|
|
Loading…
Reference in a new issue