Skip to content

Commit 19f5b19

Browse files
authored
Merge pull request #4160 from benjiwheeler/load-fonts-in-redux
refactored font loading state to be in redux
2 parents 54c8588 + 8a9996b commit 19f5b19

File tree

5 files changed

+54
-12
lines changed

5 files changed

+54
-12
lines changed

src/lib/font-loader-hoc.jsx

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
import omit from 'lodash.omit';
4+
import {connect} from 'react-redux';
5+
import {setFontsLoaded} from '../reducers/fonts-loaded';
26

37
/* Higher Order Component to provide behavior for loading fonts.
48
* @param {React.Component} WrappedComponent component to receive fontsLoaded prop
59
* @returns {React.Component} component with font loading behavior
610
*/
711
const FontLoaderHOC = function (WrappedComponent) {
812
class FontLoaderComponent extends React.Component {
9-
constructor (props) {
10-
super(props);
11-
this.state = {
12-
fontsLoaded: false
13-
};
14-
}
1513
componentDidMount () {
14+
if (this.props.fontsLoaded) return;
15+
1616
const getFontPromises = () => {
1717
const fontPromises = [];
1818
// Browsers that support the font loader interface have an iterable document.fonts.values()
@@ -32,28 +32,43 @@ const FontLoaderHOC = function (WrappedComponent) {
3232
// objects get replaced and the old ones never resolve.
3333
if (document.readyState === 'complete') {
3434
Promise.all(getFontPromises()).then(() => {
35-
this.setState({fontsLoaded: true});
35+
this.props.onSetFontsLoaded();
3636
});
3737
} else {
3838
document.onreadystatechange = () => {
3939
if (document.readyState !== 'complete') return;
4040
document.onreadystatechange = null;
4141
Promise.all(getFontPromises()).then(() => {
42-
this.setState({fontsLoaded: true});
42+
this.props.onSetFontsLoaded();
4343
});
4444
};
4545
}
4646
}
4747
render () {
48+
const componentProps = omit(this.props, ['onSetFontsLoaded']);
4849
return (
4950
<WrappedComponent
50-
fontsLoaded={this.state.fontsLoaded}
51-
{...this.props}
51+
{...componentProps}
5252
/>
5353
);
5454
}
5555
}
56-
return FontLoaderComponent;
56+
57+
58+
FontLoaderComponent.propTypes = {
59+
fontsLoaded: PropTypes.bool.isRequired,
60+
onSetFontsLoaded: PropTypes.func.isRequired
61+
};
62+
const mapStateToProps = state => ({
63+
fontsLoaded: state.scratchGui.fontsLoaded
64+
});
65+
const mapDispatchToProps = dispatch => ({
66+
onSetFontsLoaded: () => dispatch(setFontsLoaded())
67+
});
68+
return connect(
69+
mapStateToProps,
70+
mapDispatchToProps
71+
)(FontLoaderComponent);
5772
};
5873

5974
export {

src/lib/vm-manager-hoc.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ const vmManagerHOC = function (WrappedComponent) {
120120
const mapStateToProps = state => {
121121
const loadingState = state.scratchGui.projectState.loadingState;
122122
return {
123+
fontsLoaded: state.scratchGui.fontsLoaded,
123124
isLoadingWithId: getIsLoadingWithId(loadingState),
124125
projectData: state.scratchGui.projectState.projectData,
125126
projectId: state.scratchGui.projectState.projectId,

src/reducers/fonts-loaded.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
const SET_FONTS_LOADED = 'fontsLoaded/SET_FONTS_LOADED';
2+
3+
const initialState = false;
4+
5+
const reducer = function (state, action) {
6+
if (typeof state === 'undefined') state = initialState;
7+
switch (action.type) {
8+
case SET_FONTS_LOADED:
9+
return action.loaded;
10+
default:
11+
return state;
12+
}
13+
};
14+
const setFontsLoaded = () => ({
15+
type: SET_FONTS_LOADED,
16+
loaded: true
17+
});
18+
19+
export {
20+
reducer as default,
21+
initialState as fontsLoadedInitialState,
22+
setFontsLoaded
23+
};

src/reducers/gui.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import monitorLayoutReducer, {monitorLayoutInitialState} from './monitor-layout'
1717
import projectChangedReducer, {projectChangedInitialState} from './project-changed';
1818
import projectStateReducer, {projectStateInitialState} from './project-state';
1919
import projectTitleReducer, {projectTitleInitialState} from './project-title';
20+
import fontsLoadedReducer, {fontsLoadedInitialState} from './fonts-loaded';
2021
import restoreDeletionReducer, {restoreDeletionInitialState} from './restore-deletion';
2122
import stageSizeReducer, {stageSizeInitialState} from './stage-size';
2223
import targetReducer, {targetsInitialState} from './targets';
@@ -50,6 +51,7 @@ const guiInitialState = {
5051
projectChanged: projectChangedInitialState,
5152
projectState: projectStateInitialState,
5253
projectTitle: projectTitleInitialState,
54+
fontsLoaded: fontsLoadedInitialState,
5355
restoreDeletion: restoreDeletionInitialState,
5456
targets: targetsInitialState,
5557
timeout: timeoutInitialState,
@@ -146,6 +148,7 @@ const guiReducer = combineReducers({
146148
projectChanged: projectChangedReducer,
147149
projectState: projectStateReducer,
148150
projectTitle: projectTitleReducer,
151+
fontsLoaded: fontsLoadedReducer,
149152
restoreDeletion: restoreDeletionReducer,
150153
targets: targetReducer,
151154
timeout: timeoutReducer,

src/reducers/project-state.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ const onLoadedProject = (loadingState, canSave, success) => {
452452
type: DONE_LOADING_VM_WITHOUT_ID
453453
};
454454
default:
455-
break;
455+
return;
456456
}
457457
}
458458
return {

0 commit comments

Comments
 (0)