From 8ba954c74326045f9d4e36e6f13edb239f24d5a1 Mon Sep 17 00:00:00 2001 From: Jeff Avallone Date: Mon, 28 May 2018 14:41:02 -0400 Subject: [PATCH] Loading rendering code dynamically --- src/components/App/index.js | 88 +++++++++++++++++++++++++++++------- src/components/App/style.css | 41 +++++++++++++++++ 2 files changed, 112 insertions(+), 17 deletions(-) diff --git a/src/components/App/index.js b/src/components/App/index.js index 88de33c..150195a 100644 --- a/src/components/App/index.js +++ b/src/components/App/index.js @@ -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 {

Sample warning message

- { image &&
- -
} + { + loading &&
+ +
Loading...
+
+ } + { + loadingFailed && + An error occurred while rendering the regular expression. Retry + + } + { + image &&
+ +
+ } ; } } diff --git a/src/components/App/style.css b/src/components/App/style.css index afafb4f..82b6eae 100644 --- a/src/components/App/style.css +++ b/src/components/App/style.css @@ -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); + } +}