Loading rendering code dynamically

This commit is contained in:
Jeff Avallone 2018-05-28 14:41:02 -04:00
parent d88defcc65
commit 8ba954c743
2 changed files with 112 additions and 17 deletions

View File

@ -2,12 +2,14 @@ import React from 'react';
import PropTypes from 'prop-types';
import { translate } from 'react-i18next';
import URLSearchParams from 'url-search-params';
import Raven from 'raven-js';
import LoaderIcon from 'feather-icons/dist/icons/loader.svg';
import style from './style.css';
import Form from 'components/Form';
import Message from 'components/Message';
import SVG from 'components/SVG';
import { demoImage } from 'devel';
const syntaxes = {
@ -67,6 +69,34 @@ class App extends React.PureComponent {
}
}
async loadSVGComponent() {
if (this.state.SVG) {
return;
}
this.setState({
loading: true,
loadingFailed: false
});
try {
const SVG = await import(/* webpackChunkName: "render" */ 'components/SVG');
this.setState({
SVG: SVG.default,
loading: false
});
}
catch (e) {
Raven.captureException(e);
this.setState({
loading: false,
loadingFailed: e
});
throw e;
}
}
handleSubmit = ({expr, syntax}) => {
if (expr) {
const params = new URLSearchParams({ syntax, expr });
@ -74,7 +104,7 @@ class App extends React.PureComponent {
}
}
handleHashChange = () => {
handleHashChange = async () => {
const query = document.location.hash.slice(1);
const params = new URLSearchParams(query);
const { expr, syntax } = (() => {
@ -96,21 +126,32 @@ class App extends React.PureComponent {
return;
}
console.log(syntax, expr); // eslint-disable-line no-console
this.setState({
image: demoImage,
permalinkUrl: document.location.toString(),
syntax,
expr
}, async () => {
await this.image.current.doReflow();
this.setSvgUrl();
this.setPngUrl();
});
try {
await this.loadSVGComponent();
console.log(syntax, expr); // eslint-disable-line no-console
this.setState({
image: demoImage,
permalinkUrl: document.location.toString(),
syntax,
expr
}, async () => {
await this.image.current.doReflow();
this.setSvgUrl();
this.setPngUrl();
});
}
catch (e) {
console.error(e); // eslint-disable-line no-console
}
}
handleRetry = async event => {
event.preventDefault();
this.handleHashChange();
}
render() {
const { svgUrl, pngUrl, permalinkUrl, syntax, expr, image } = this.state;
const { SVG, loading, loadingFailed, svgUrl, pngUrl, permalinkUrl, syntax, expr, image } = this.state;
const downloadUrls = [
svgUrl,
pngUrl
@ -130,9 +171,22 @@ class App extends React.PureComponent {
<Message type="warning" heading="Sample Warning">
<p>Sample warning message</p>
</Message>
{ image && <div className={ style.render }>
<SVG data={ image } ref={ this.image }/>
</div> }
{
loading && <div className={ style.loader }>
<LoaderIcon />
<div className={ style.message }>Loading...</div>
</div>
}
{
loadingFailed && <Message type="error" heading="Render Failure">
An error occurred while rendering the regular expression. <a href="#retry" onClick={ this.handleRetry }>Retry</a>
</Message>
}
{
image && <div className={ style.render }>
<SVG data={ image } ref={ this.image }/>
</div>
}
</React.Fragment>;
}
}

View File

@ -13,3 +13,44 @@
margin: 0 auto;
}
}
.loader {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%;
padding: 2rem;
background: var(--color-white);
color: var(--color-black);
& .message {
font-weight: bold;
font-size: 2.5rem;
padding: 0;
text-align: center;
}
& svg {
display: block;
transform: scaleZ(1); /* Move to separate render layer in Chrome */
width: 5rem;
height: 5rem;
stroke: var(--color-black);
animation: loader-spin 1s steps(8) infinite;
& line:nth-of-type(1) { stroke: color(var(--color-black) alpha(0.75)); }
& line:nth-of-type(3) { stroke: color(var(--color-black) alpha(0.50)); }
& line:nth-of-type(5) { stroke: color(var(--color-black) alpha(0.25)); }
& line:nth-of-type(7) { stroke: color(var(--color-black) alpha(0)); }
}
}
@keyframes loader-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}