diff --git a/.eslintrc.yml b/.eslintrc.yml index c5b772a..71fb744 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -10,9 +10,9 @@ parser: babel-eslint plugins: - import - react + - react-hooks - jest - extends: - eslint:recommended - plugin:import/errors @@ -31,3 +31,4 @@ rules: react/jsx-uses-react: "error" react/jsx-uses-vars: "error" react/react-in-jsx-scope: "error" + react-hooks/rules-of-hooks: error diff --git a/assets/yacd.ico b/assets/yacd.ico new file mode 100644 index 0000000..ec4e470 Binary files /dev/null and b/assets/yacd.ico differ diff --git a/package.json b/package.json index b3e6353..22c9386 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "modern-normalize": "^0.5.0", "prop-types": "^15.5.10", "react": "^16.7.0-alpha.0", + "react-cache": "^2.0.0-alpha.0", "react-dom": "^16.7.0-alpha.0", "react-modal": "^3.6.1", "react-redux": "^6.0.0-alpha.2a2f108", @@ -71,6 +72,7 @@ "eslint-plugin-import": "2.14.0", "eslint-plugin-jest": "^21.26.1", "eslint-plugin-react": "7.11.1", + "eslint-plugin-react-hooks": "^0.0.0", "file-loader": "^2.0.0", "html-webpack-plugin": "^3.2.0", "husky": "^1.0.1", diff --git a/src/api/logs.js b/src/api/logs.js index a9d358b..b39e924 100644 --- a/src/api/logs.js +++ b/src/api/logs.js @@ -26,6 +26,7 @@ let even = false; const store = { logs: [], size: Size, + fetched: false, subscribers: [], appendData(o) { const now = new Date(); @@ -68,15 +69,19 @@ function pump(reader) { }); } -let fetched = false; function fetchLogs() { - if (fetched) return store; + if (store.fetched) return store; + store.fetched = true; const { url, init } = getURLAndInit(); - fetch(url, init).then(response => { - fetched = true; - const reader = response.body.getReader(); - pump(reader); - }); + fetch(url, init) + .then(response => { + const reader = response.body.getReader(); + pump(reader); + }) + .catch(err => { + store.fetched = false; + console.log('Error', err); + }); return store; } diff --git a/src/components/Home.js b/src/components/Home.js index cf417a4..57f6c6f 100644 --- a/src/components/Home.js +++ b/src/components/Home.js @@ -1,8 +1,9 @@ -import React from 'react'; +import React, { Suspense } from 'react'; import ContentHeader from 'c/ContentHeader'; import TrafficChart from 'c/TrafficChart'; import TrafficNow from 'c/TrafficNow'; +import Loading from 'c/Loading'; import s0 from 'c/Home.module.scss'; export default function Home() { @@ -14,7 +15,9 @@ export default function Home() {
- + } maxDuration={10}> + +
diff --git a/src/components/Loading.js b/src/components/Loading.js index 1b8d373..7949a4b 100644 --- a/src/components/Loading.js +++ b/src/components/Loading.js @@ -1,14 +1,19 @@ import React from 'react'; +import PropTypes from 'prop-types'; -import style from './Loading.module.scss'; +import s0 from './Loading.module.scss'; -const Loading = () => { +const Loading = ({ height }) => { + const style = height ? { height } : {}; return ( -
-
-
+
+
); }; +Loading.propTypes = { + height: PropTypes.string +}; + export default Loading; diff --git a/src/components/Loading.module.scss b/src/components/Loading.module.scss index 7166140..05f8f3f 100644 --- a/src/components/Loading.module.scss +++ b/src/components/Loading.module.scss @@ -1,50 +1,31 @@ -$color1: #2a477a; -$color2: #dddddd; +// $color1: #2a477a; +$color1: #dddddd; -@keyframes moveRight { - 0% { - transform: translate(-50px); - } - - 100% { - transform: translate(10px); - } -} - -@keyframes moveLeft { - 0% { - transform: translate(50px); - } - - 100% { - transform: translate(-10px); - } -} +$size: 40px; .loading { - position: relative; width: 100%; - height: 300px; - margin: 0 auto; - height: 30vh; + height: 100%; + display: flex; + justify-content: center; + align-items: center; } -.circle { - width: 40px; - height: 40px; - border-radius: 50%; - position: absolute; - top: 50%; -} - -.left { +.pulse { + width: $size; + height: $size; + margin: 10px; background-color: $color1; - left: 50%; - animation: moveRight 1s ease-in-out 0s infinite alternate; + border-radius: 100%; + animation: pulseScaleOut 1s infinite ease-in-out; } -.right { - background-color: $color2; - right: 50%; - animation: moveLeft 1s ease-in-out 0s infinite alternate; +@keyframes pulseScaleOut { + 0% { + transform: scale(0); + } + 100% { + transform: scale(1); + opacity: 0; + } } diff --git a/src/components/Logs.js b/src/components/Logs.js index 74cdb33..235e7ba 100644 --- a/src/components/Logs.js +++ b/src/components/Logs.js @@ -47,7 +47,7 @@ export default function Logs() { const x = fetchLogs(); setLogs(x.logs); return x.subscribe(() => setLogs(x.logs)); - }); + }, []); return (
diff --git a/src/components/TrafficChart.js b/src/components/TrafficChart.js index f625d90..4bfb4a7 100644 --- a/src/components/TrafficChart.js +++ b/src/components/TrafficChart.js @@ -1,8 +1,12 @@ import React, { useEffect } from 'react'; -import Chart from 'chart.js/dist/Chart.min.js'; import prettyBytes from 'm/pretty-bytes'; - import { fetchData } from '../api/traffic'; +import { unstable_createResource as createResource } from 'react-cache'; + +// const delay = ms => new Promise(r => setTimeout(r, ms)); +const chartJSResource = createResource(() => { + return import('chart.js/dist/Chart.min.js').then(c => c.default); +}); const colorCombo = { 0: { @@ -108,13 +112,15 @@ const options = { }; const chartWrapperStyle = { + // make chartjs chart responsive position: 'relative', width: '90%' }; export default function TrafficChart() { + const Chart = chartJSResource.read(); useEffect(() => { - const ctx = document.getElementById('myChart').getContext('2d'); + const ctx = document.getElementById('trafficChart').getContext('2d'); const traffic = fetchData(); const data = { labels: traffic.labels, @@ -139,7 +145,7 @@ export default function TrafficChart() { return (
- +
); } diff --git a/src/index.template.ejs b/src/index.template.ejs index 42b15da..a05a997 100644 --- a/src/index.template.ejs +++ b/src/index.template.ejs @@ -2,13 +2,14 @@ + + + - - <%= htmlWebpackPlugin.options.title %> diff --git a/webpack.config.js b/webpack.config.js index 3f97ceb..5063cf8 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -106,11 +106,11 @@ module.exports = { // test: /[\\/]node_modules[\\/](core-js)[\\/]/, // chunks: 'all' // }, - chartjs: { - test: /[\\/]node_modules[\\/]chart\.js[\\/]/, - // name: 'chartjs', - chunks: 'all' - }, + // chartjs: { + // test: /[\\/]node_modules[\\/]chart\.js[\\/]/, + // // name: 'chartjs', + // chunks: 'all' + // }, react: { test: /[\\/]node_modules[\\/](react-dom|react|redux|react-router|react-router-dom|schedule|react-redux|react-modal)[\\/]/, chunks: 'all' diff --git a/yarn.lock b/yarn.lock index a307ecd..6e384e3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2919,6 +2919,11 @@ eslint-plugin-jest@^21.26.1: resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-21.26.2.tgz#5b24413970e83e2c5b87c5c047a08a4881783605" integrity sha512-SCTBC6q182D4qQlQAN81D351jdte/YwTMo4f+l19Gvh1VemaNZP7ak3MLLvw6xkL9dO2FxVjCLk5DCdl1KfdLw== +eslint-plugin-react-hooks@^0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-0.0.0.tgz#9988f14082a159931c3dfa9ba699130457da927a" + integrity sha512-SXyU7C3E8AJbXKMdb10P/zHazcxzfuWR5OFwAVZKXVU7P/H56NLszVG6WdQBo9Pt80FfnPXtUGGbWhs3/98N4w== + eslint-plugin-react@7.11.1: version "7.11.1" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.11.1.tgz#c01a7af6f17519457d6116aa94fc6d2ccad5443c" @@ -6603,6 +6608,11 @@ rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" +react-cache@^2.0.0-alpha.0: + version "2.0.0-alpha.0" + resolved "https://registry.yarnpkg.com/react-cache/-/react-cache-2.0.0-alpha.0.tgz#d02d16a4565fd9f12478a2a41e980ba4fcbab4d5" + integrity sha512-o7nA1dIbi6wOoIoQPQBL58CgIQ4tCA3itIR3WlE2VHMIFkIXbvsMyolg+Q9wDVUlCvU6b2n40RTTv8vOmjXCOQ== + react-dom@^16.7.0-alpha.0: version "16.7.0-alpha.0" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.7.0-alpha.0.tgz#8379158d4c76d63c989f325f45dfa5762582584f"