Skip to content
Snippets Groups Projects
Commit 5542becc authored by Paul Kaplan's avatar Paul Kaplan
Browse files

Add fetching and loading states to display loading screen.

parent 89214e16
No related branches found
No related tags found
No related merge requests found
......@@ -14,7 +14,7 @@ import TargetPane from '../../containers/target-pane.jsx';
import SoundTab from '../../containers/sound-tab.jsx';
import StageHeader from '../../containers/stage-header.jsx';
import Stage from '../../containers/stage.jsx';
import Loader from '../loader/loader.jsx';
import Box from '../box/box.jsx';
import FeedbackForm from '../feedback-form/feedback-form.jsx';
import MenuBar from '../menu-bar/menu-bar.jsx';
......@@ -44,6 +44,7 @@ const GUIComponent = props => {
feedbackFormVisible,
importInfoVisible,
intl,
loading,
onExtensionButtonClick,
onActivateTab,
previewInfoVisible,
......@@ -78,6 +79,9 @@ const GUIComponent = props => {
{previewInfoVisible ? (
<PreviewModal />
) : null}
{loading ? (
<Loader />
) : null}
{importInfoVisible ? (
<ImportModal />
) : null}
......@@ -176,6 +180,7 @@ GUIComponent.propTypes = {
feedbackFormVisible: PropTypes.bool,
importInfoVisible: PropTypes.bool,
intl: intlShape.isRequired,
loading: PropTypes.bool,
onActivateTab: PropTypes.func,
onExtensionButtonClick: PropTypes.func,
onTabSelect: PropTypes.func,
......
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
@import "../../css/colors.css";
.background {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 999; /* Below preview modal */
display: flex;
justify-content: center;
align-items: center;
background-color: $motion-primary;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
text-align: center;
color: white;
}
.block-animation {
width: 125px;
height: 150px;
margin: 50px auto 0px;
}
.block-animation img {
display: block;
position: relative;
height: 30%;
margin-top: -4px;
}
.topBlock {
animation: top-slide-in 1.5s ease infinite;
}
.middleBlock {
animation: middle-slide-in 1.5s ease infinite;
}
.bottomBlock {
animation: bottom-slide-in 1.5s ease infinite;
}
@keyframes top-slide-in {
0% {
transform: translateY(50px);
opacity: 0;
}
33% {
transform: translateY(0px);
opacity: 1;
}
}
@keyframes middle-slide-in {
0% {
transform: translateY(50px);
opacity: 0;
}
33% {
transform: translateY(50px);
opacity: 0;
}
66% {
transform: translateY(0px);
opacity: 1;
}
}
@keyframes bottom-slide-in {
0% {
transform: translateY(50px);
opacity: 0;
}
66% {
transform: translateY(50px);
opacity: 0;
}
100% {
transform: translateY(0px);
opacity: 1;
}
}
import React from 'react';
import {FormattedMessage} from 'react-intl';
import styles from './loader.css';
import topBlock from './top-block.svg';
import middleBlock from './middle-block.svg';
import bottomBlock from './bottom-block.svg';
const LoaderComponent = () => {
const messages = [
{
message: (
<FormattedMessage
defaultMessage="Creating blocks …"
description="One of the loading messages"
id="gui.loader.message1"
/>
),
weight: 50
},
{
message: (
<FormattedMessage
defaultMessage="Loading sprites …"
description="One of the loading messages"
id="gui.loader.message2"
/>
),
weight: 50
},
{
message: (
<FormattedMessage
defaultMessage="Loading sounds …"
description="One of the loading messages"
id="gui.loader.message3"
/>
),
weight: 50
},
{
message: (
<FormattedMessage
defaultMessage="Loading extensions …"
description="One of the loading messages"
id="gui.loader.message4"
/>
),
weight: 50
},
{
message: (
<FormattedMessage
defaultMessage="Creating blocks …"
description="One of the loading messages"
id="gui.loader.message1"
/>
),
weight: 20
},
{
message: (
<FormattedMessage
defaultMessage="Herding cats …"
description="One of the loading messages"
id="gui.loader.message5"
/>
),
weight: 1
},
{
message: (
<FormattedMessage
defaultMessage="Transmitting nanos …"
description="One of the loading messages"
id="gui.loader.message6"
/>
),
weight: 1
},
{
message: (
<FormattedMessage
defaultMessage="Inflating gobos …"
description="One of the loading messages"
id="gui.loader.message7"
/>
),
weight: 1
},
{
message: (
<FormattedMessage
defaultMessage="Preparing emojiis …"
description="One of the loading messages"
id="gui.loader.message8"
/>
),
weight: 1
}
];
let message;
const sum = messages.reduce((acc, m) => acc + m.weight, 0);
let rand = sum * Math.random();
for (let i = 0; i < messages.length; i++) {
rand -= messages[i].weight;
if (rand <= 0) {
message = messages[i].message;
break;
}
}
return (
<div className={styles.background}>
<div className={styles.container}>
<div className={styles.blockAnimation}>
<img
className={styles.topBlock}
src={topBlock}
/>
<img
className={styles.middleBlock}
src={middleBlock}
/>
<img
className={styles.bottomBlock}
src={bottomBlock}
/>
</div>
<h1 className={styles.title}>
<FormattedMessage
defaultMessage="Loading Project"
description="Main loading message"
id="gui.loader.headline"
/>
</h1>
<p>{message}</p>
</div>
</div>
);
};
export default LoaderComponent;
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
......@@ -17,16 +17,29 @@ import vmListenerHOC from '../lib/vm-listener-hoc.jsx';
import GUIComponent from '../components/gui/gui.jsx';
class GUI extends React.Component {
constructor (props) {
super(props);
this.state = {
loading: true
};
}
componentDidMount () {
this.audioEngine = new AudioEngine();
this.props.vm.attachAudioEngine(this.audioEngine);
this.props.vm.loadProject(this.props.projectData);
this.props.vm.setCompatibilityMode(true);
this.props.vm.start();
this.props.vm.loadProject(this.props.projectData).then(() => {
this.setState({loading: false}, () => {
this.props.vm.setCompatibilityMode(true);
this.props.vm.start();
});
});
}
componentWillReceiveProps (nextProps) {
if (this.props.projectData !== nextProps.projectData) {
this.props.vm.loadProject(nextProps.projectData);
this.setState({loading: true}, () => {
this.props.vm.loadProject(nextProps.projectData).then(() => {
this.setState({loading: false});
});
});
}
}
componentWillUnmount () {
......@@ -35,12 +48,14 @@ class GUI extends React.Component {
render () {
const {
children,
fetchingProject,
projectData, // eslint-disable-line no-unused-vars
vm,
...componentProps
} = this.props;
return (
<GUIComponent
loading={fetchingProject || this.state.loading}
vm={vm}
{...componentProps}
>
......@@ -53,6 +68,7 @@ class GUI extends React.Component {
GUI.propTypes = {
...GUIComponent.propTypes,
feedbackFormVisible: PropTypes.bool,
fetchingProject: PropTypes.bool,
importInfoVisible: PropTypes.bool,
previewInfoVisible: PropTypes.bool,
projectData: PropTypes.string,
......
......@@ -17,21 +17,25 @@ const ProjectLoaderHOC = function (WrappedComponent) {
this.updateProject = this.updateProject.bind(this);
this.state = {
projectId: null,
projectData: null
projectData: null,
fetchingProject: false
};
}
componentDidMount () {
window.addEventListener('hashchange', this.updateProject);
this.updateProject();
}
componentDidUpdate (prevProps, prevState) {
if (this.state.projectId !== prevState.projectId) {
storage
.load(storage.AssetType.Project, this.state.projectId, storage.DataFormat.JSON)
.then(projectAsset => projectAsset && this.setState({
projectData: projectAsset.data.toString()
}))
.catch(err => log.error(err));
componentWillUpdate (nextProps, nextState) {
if (this.state.projectId !== nextState.projectId) {
this.setState({fetchingProject: true}, () => {
storage
.load(storage.AssetType.Project, this.state.projectId, storage.DataFormat.JSON)
.then(projectAsset => projectAsset && this.setState({
projectData: projectAsset.data.toString(),
fetchingProject: false
}))
.catch(err => log.error(err));
});
}
}
componentWillUnmount () {
......@@ -60,6 +64,7 @@ const ProjectLoaderHOC = function (WrappedComponent) {
if (!this.state.projectData) return null;
return (
<WrappedComponent
fetchingProject={this.state.fetchingProject}
projectData={this.state.projectData}
{...this.props}
/>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment