Spaces:
Runtime error
Runtime error
File size: 7,889 Bytes
8fd7a1d |
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 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
import React from 'react';
import {FormattedMessage, injectIntl, intlShape, defineMessages} from 'react-intl';
import {connect} from 'react-redux';
import classNames from 'classnames';
import PropTypes from 'prop-types';
import bindAll from 'lodash.bindall';
import styles from './loader.css';
import {getIsLoadingWithId} from '../../reducers/project-state';
import topBlock from './top-block.svg';
import middleBlock from './middle-block.svg';
import bottomBlock from './bottom-block.svg';
const mainMessages = {
'gui.loader.headline': (
<FormattedMessage
defaultMessage="Loading Project"
description="Main loading message"
id="gui.loader.headline"
/>
),
'gui.loader.creating': (
<FormattedMessage
defaultMessage="Creating Project"
description="Main creating message"
id="gui.loader.creating"
/>
)
};
const messages = defineMessages({
projectData: {
defaultMessage: 'Loading project …',
description: 'Appears when loading project data, but not assets yet',
id: 'tw.loader.projectData'
},
downloadingAssets: {
defaultMessage: 'Downloading assets ({complete}/{total}) …',
description: 'Appears when loading project assets from a project on a remote website',
id: 'tw.loader.downloadingAssets'
},
loadingAssets: {
defaultMessage: 'Loading assets ({complete}/{total}) …',
description: 'Appears when loading project assets from a project file on the user\'s computer',
id: 'tw.loader.loadingAssets'
}
});
// Array of random loading messages
const randomMessages = [
"MistWarp's anniversary is less than a year away! - Nameless",
"ur gay - Flufi",
"that is making my braincells consider dying as their next action - JustNoone",
"i moved the addons tab to edit because i like it :yum: - Mistium",
"OH MY FLIPPERS - roturBOT",
"we have more themes than TurboWarp, which makes MistWarp better - Mistium",
"Femboys can be not gray - JustNoone",
"Penguinmod cringe fr fr ong no cap (real) (not gone wrong) (mistwarp better real) - Flufi",
"Fences are always gray - Nameless",
"Dont try, dont try to hide it - Flufi",
"CSS is my passion - Nameless",
"CSS is a turing complete scripting language - Mistium",
"I want to be Poland - Andrew",
"Programer socks are part of the official MistWarp uniform - Nameless",
"Wear thigh highs or die :3 - Flufi",
"This mod has no swears, pg family friendly - Mistium",
"Grah - Flufi",
"I am a professional MistWarp user - Nameless",
"Next person to be confused by this quote is gay - Flufi",
"Look under there",
"do not the mistwarp - Flufi",
"how sign in to mistwarp - Andrew",
"if only mistwarp was less mist and more warp - Mistium",
"i just laughed so hard i died - Flufi",
"I just laughed so hard that I just laughed so hard - ViMi",
"i own turbowarp and penguinmod - Andrew"
];
// Because progress events are fired so often during the very performance-critical loading
// process and React updates are very slow, we bypass React for updating the progress bar.
class LoaderComponent extends React.Component {
constructor (props) {
super(props);
bindAll(this, [
'handleAssetProgress',
'handleProjectLoaded',
'barInnerRef',
'messageRef'
]);
this.barInnerEl = null;
this.messageEl = null;
this.ignoreProgress = false;
// Select a random message when the component is created
this.randomMessage = randomMessages[Math.floor(Math.random() * randomMessages.length)];
}
componentDidMount () {
this.handleAssetProgress(
this.props.vm.runtime.finishedAssetRequests,
this.props.vm.runtime.totalAssetRequests
);
this.props.vm.on('ASSET_PROGRESS', this.handleAssetProgress);
this.props.vm.runtime.on('PROJECT_LOADED', this.handleProjectLoaded);
}
componentWillUnmount () {
this.props.vm.off('ASSET_PROGRESS', this.handleAssetProgress);
this.props.vm.runtime.off('PROJECT_LOADED', this.handleProjectLoaded);
}
handleAssetProgress (finished, total) {
if (this.ignoreProgress || !this.barInnerEl || !this.messageEl) {
return;
}
if (total === 0) {
// Started loading a new project.
this.barInnerEl.style.width = '0';
this.messageEl.textContent = this.props.intl.formatMessage(messages.projectData);
} else {
this.barInnerEl.style.width = `${finished / total * 100}%`;
const message = this.props.isRemote ? messages.downloadingAssets : messages.loadingAssets
this.messageEl.textContent = this.props.intl.formatMessage(message, {
complete: finished,
total
});
}
}
handleProjectLoaded () {
if (this.ignoreProgress || !this.barInnerEl || !this.messageEl) {
return;
}
this.ignoreProgress = true;
this.props.vm.runtime.resetProgress();
}
barInnerRef (barInner) {
this.barInnerEl = barInner;
}
messageRef (message) {
this.messageEl = message;
}
render () {
return (
<div
className={classNames(styles.background, {
[styles.fullscreen]: this.props.isFullScreen
})}
>
<div className={styles.container}>
<div className={styles.blockAnimation}>
<img
className={styles.topBlock}
src={topBlock}
draggable={false}
/>
<img
className={styles.middleBlock}
src={middleBlock}
draggable={false}
/>
<img
className={styles.bottomBlock}
src={bottomBlock}
draggable={false}
/>
</div>
<div className={styles.title}>
{mainMessages[this.props.messageId]}
</div>
<div
className={styles.message}
ref={this.messageRef}
/>
<div className={styles.barOuter}>
<div
className={styles.barInner}
ref={this.barInnerRef}
/>
</div>
<div className={styles.randomMessage}>
{this.randomMessage}
</div>
</div>
</div>
);
}
}
LoaderComponent.propTypes = {
intl: intlShape,
isFullScreen: PropTypes.bool,
isRemote: PropTypes.bool,
messageId: PropTypes.string,
vm: PropTypes.shape({
on: PropTypes.func,
off: PropTypes.func,
runtime: PropTypes.shape({
totalAssetRequests: PropTypes.number,
finishedAssetRequests: PropTypes.number,
resetProgress: PropTypes.func,
on: PropTypes.func,
off: PropTypes.func
})
})
};
LoaderComponent.defaultProps = {
isFullScreen: false,
messageId: 'gui.loader.headline'
};
const mapStateToProps = state => ({
isRemote: getIsLoadingWithId(state.scratchGui.projectState.loadingState),
vm: state.scratchGui.vm
});
const mapDispatchToProps = () => ({});
export default connect(
mapStateToProps,
mapDispatchToProps
)(injectIntl(LoaderComponent));
|