penguinmod-editor-2 / src /playground /playground-interface.jsx
soiz1's picture
Upload 2891 files
6bcb42f verified
/**
* Copyright (C) 2021 Thomas Weber
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import classNames from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';
import { connect } from 'react-redux';
import { compose } from 'redux';
import { FormattedMessage, defineMessages, injectIntl, intlShape } from 'react-intl';
import { getIsLoading } from '../reducers/project-state.js';
import DOMElementRenderer from '../containers/dom-element-renderer.jsx';
import AppStateHOC from '../lib/app-state-hoc.jsx';
import ErrorBoundaryHOC from '../lib/error-boundary-hoc.jsx';
import TWProjectMetaFetcherHOC from '../lib/tw-project-meta-fetcher-hoc.jsx';
import TWStateManagerHOC from '../lib/tw-state-manager-hoc.jsx';
import TWThemeHOC from '../lib/tw-theme-hoc.jsx';
import TWPackagerIntegrationHOC from '../lib/tw-packager-integration-hoc.jsx';
import SettingsStore from '../addons/settings-store-singleton';
import '../lib/tw-fix-history-api';
import GUI from './render-gui.jsx';
import AddonChannels from '../addons/channels';
import { loadServiceWorker } from './load-service-worker';
import runAddons from '../addons/entry';
import styles from './interface.css';
const messages = defineMessages({
defaultTitle: {
defaultMessage: 'Playground',
description: 'Title of homepage',
id: 'pm.playgroundDefaultTitle'
}
});
if (AddonChannels.reloadChannel) {
AddonChannels.reloadChannel.addEventListener('message', () => {
location.reload();
});
}
if (AddonChannels.changeChannel) {
AddonChannels.changeChannel.addEventListener('message', e => {
SettingsStore.setStoreWithVersionCheck(e.data);
});
}
runAddons();
class Interface extends React.Component {
constructor(props) {
super(props);
this.handleUpdateProjectTitle = this.handleUpdateProjectTitle.bind(this);
}
componentDidUpdate(prevProps) {
if (prevProps.isLoading && !this.props.isLoading) {
loadServiceWorker();
}
}
handleUpdateProjectTitle(title, isDefault) {
if (isDefault || !title) {
document.title = `PenguinMod - ${this.props.intl.formatMessage(messages.defaultTitle)}`;
} else {
document.title = `${title} - PenguinMod`;
}
}
render() {
const {
/* eslint-disable no-unused-vars */
intl,
hasCloudVariables,
description,
isFullScreen,
isLoading,
isPlayerOnly,
isRtl,
onClickTheme,
projectId,
/* eslint-enable no-unused-vars */
...props
} = this.props;
const isHomepage = false;
const isEditor = true;
return (
<div
className={classNames(styles.container, {
[styles.playerOnly]: isHomepage,
[styles.editor]: isEditor
})}
>
<div
className={styles.center}
style={isPlayerOnly ? ({
// add a couple pixels to account for border (TODO: remove weird hack)
width: `${Math.max(480, props.customStageSize.width) + 2}px`
}) : null}
>
<GUI
onClickTheme={onClickTheme}
isPlayground={true}
onUpdateProjectTitle={this.handleUpdateProjectTitle}
backpackVisible
backpackHost="_local_"
{...props}
/>
</div>
</div>
);
}
}
Interface.propTypes = {
intl: intlShape,
hasCloudVariables: PropTypes.bool,
customStageSize: PropTypes.shape({
width: PropTypes.number,
height: PropTypes.number
}),
description: PropTypes.shape({
credits: PropTypes.string,
instructions: PropTypes.string
}),
isFullScreen: PropTypes.bool,
isLoading: PropTypes.bool,
isPlayerOnly: PropTypes.bool,
isRtl: PropTypes.bool,
onClickTheme: PropTypes.func,
projectId: PropTypes.string
};
const mapStateToProps = state => ({
hasCloudVariables: state.scratchGui.tw.hasCloudVariables,
customStageSize: state.scratchGui.customStageSize,
description: state.scratchGui.tw.description,
isFullScreen: state.scratchGui.mode.isFullScreen,
isLoading: getIsLoading(state.scratchGui.projectState.loadingState),
isPlayerOnly: state.scratchGui.mode.isPlayerOnly,
isRtl: state.locales.isRtl,
projectId: state.scratchGui.projectState.projectId
});
const mapDispatchToProps = () => ({});
const ConnectedInterface = injectIntl(connect(
mapStateToProps,
mapDispatchToProps
)(Interface));
const WrappedInterface = compose(
AppStateHOC,
ErrorBoundaryHOC('TW Interface'),
TWProjectMetaFetcherHOC,
TWStateManagerHOC,
TWThemeHOC,
TWPackagerIntegrationHOC
)(ConnectedInterface);
export default WrappedInterface;