Spaces:
Running
Running
File size: 5,535 Bytes
f2bee8a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
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 AddonHooks from '../addons/hooks';
import localesReducer, {initLocale, localesInitialState} from '../reducers/locales';
import {setPlayer, setFullScreen} from '../reducers/mode.js';
import locales from '@turbowarp/scratch-l10n';
import {detectLocale} from './detect-locale';
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
/*
* Higher Order Component to provide redux state. If an `intl` prop is provided
* it will override the internal `intl` redux state
* @param {React.Component} WrappedComponent - component to provide state for
* @param {boolean} localesOnly - only provide the locale state, not everything
* required by the GUI. Used to exclude excess state when
only rendering modals, not the GUI.
* @returns {React.Component} component with redux and intl state provided
*/
const AppStateHOC = function (WrappedComponent, localesOnly) {
class AppStateWrapper extends React.Component {
constructor (props) {
super(props);
let initialState = {};
let reducers = {};
let enhancer;
let initializedLocales = localesInitialState;
const locale = detectLocale(Object.keys(locales));
if (locale !== 'en') {
initializedLocales = initLocale(initializedLocales, locale);
}
if (localesOnly) {
// Used for instantiating minimal state for the unsupported
// browser modal
reducers = {locales: localesReducer};
initialState = {locales: initializedLocales};
enhancer = composeEnhancers();
} else {
// You are right, this is gross. But it's necessary to avoid
// importing unneeded code that will crash unsupported browsers.
const guiRedux = require('../reducers/gui');
const guiReducer = guiRedux.default;
const {
guiInitialState,
guiMiddleware,
initFullScreen,
initPlayer,
initEmbedded,
initTelemetryModal
} = guiRedux;
const {ScratchPaintReducer} = require('./tw-scratch-paint');
let initializedGui = guiInitialState;
if (props.isFullScreen || props.isPlayerOnly) {
if (props.isFullScreen) {
initializedGui = initFullScreen(initializedGui);
}
if (props.isPlayerOnly) {
initializedGui = initPlayer(initializedGui);
}
} else if (props.showTelemetryModal) {
initializedGui = initTelemetryModal(initializedGui);
}
if (props.isEmbedded) {
initializedGui = initEmbedded(initializedGui);
}
reducers = {
locales: localesReducer,
scratchGui: guiReducer,
scratchPaint: ScratchPaintReducer
};
initialState = {
locales: initializedLocales,
scratchGui: initializedGui
};
enhancer = composeEnhancers(guiMiddleware);
}
const reducer = combineReducers(reducers);
const reducer2 = (previousState, action) => {
const nextState = reducer(previousState, action);
AddonHooks.appStateReducer(action, previousState, nextState);
return nextState;
};
this.store = createStore(
reducer2,
initialState,
enhancer
);
window.ReduxStore = this.store;
AddonHooks.appStateStore = this.store;
}
componentDidUpdate (prevProps) {
if (localesOnly) return;
if (prevProps.isPlayerOnly !== this.props.isPlayerOnly) {
this.store.dispatch(setPlayer(this.props.isPlayerOnly));
}
if (prevProps.isFullScreen !== this.props.isFullScreen) {
this.store.dispatch(setFullScreen(this.props.isFullScreen));
}
}
render () {
const {
isFullScreen, // eslint-disable-line no-unused-vars
isPlayerOnly, // eslint-disable-line no-unused-vars
showTelemetryModal, // eslint-disable-line no-unused-vars
...componentProps
} = this.props;
return (
<Provider store={this.store}>
<ConnectedIntlProvider>
<WrappedComponent
{...componentProps}
/>
</ConnectedIntlProvider>
</Provider>
);
}
}
AppStateWrapper.propTypes = {
isFullScreen: PropTypes.bool,
isPlayerOnly: PropTypes.bool,
isTelemetryEnabled: PropTypes.bool,
showTelemetryModal: PropTypes.bool,
isEmbedded: PropTypes.bool
};
return AppStateWrapper;
};
export default AppStateHOC;
|