From 5ca84ded5a1500ad3ea8d029b71488e8b3b74181 Mon Sep 17 00:00:00 2001
From: eug-vs <eug-vs@keemail.me>
Date: Sat, 15 Aug 2020 03:55:27 +0300
Subject: feat: ping server before showing content

---
 src/containers/Page/DynoWaiter.tsx | 64 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)
 create mode 100644 src/containers/Page/DynoWaiter.tsx

(limited to 'src/containers/Page/DynoWaiter.tsx')

diff --git a/src/containers/Page/DynoWaiter.tsx b/src/containers/Page/DynoWaiter.tsx
new file mode 100644
index 0000000..d8460bf
--- /dev/null
+++ b/src/containers/Page/DynoWaiter.tsx
@@ -0,0 +1,64 @@
+import React, { useEffect, useState, useCallback, useMemo } from 'react';
+import { makeStyles } from '@material-ui/core/styles';
+import { get } from '../../requests';
+import Loading from '../../components/Loading/Loading';
+
+const DYNO_WAKEUP_TIME = 30;
+
+const messages = [
+  '',
+  'It looks like our server is sleeping.',
+  `We need about ${DYNO_WAKEUP_TIME} seconds to wake it up.`,
+  'Please, stay with us.',
+  'You are doing good.',
+  'Almost done.'
+];
+
+const useStyles = makeStyles(theme => ({
+  root: {
+    textAlign: 'center'
+  },
+  hidden: {
+    visibility: 'hidden',
+    position: 'absolute'
+  }
+}));
+
+const DynoWaiter: React.FC = ({ children }) => {
+  const classes = useStyles();
+  const [isReady, setIsReady] = useState<boolean>(false);
+  const [time, setTime] = useState<number>(0);
+
+  const tick = useCallback((): void => setTime(value => value + 1), [setTime]);
+
+  useEffect(() => {
+    const interval = setInterval(tick, 1000);
+    get('/ping').then(() => {
+      setIsReady(true);
+      clearInterval(interval);
+    });
+    return () => clearInterval(interval);
+  }, [setIsReady, tick]);
+
+  const message = useMemo(() => {
+    const interval = DYNO_WAKEUP_TIME / messages.length;
+    const index = Math.floor(time / interval);
+    const lastIndex = messages.length - 1;
+    return messages[index > lastIndex ? lastIndex : index];
+  }, [time]);
+
+  const tagline = useMemo(() => time > 3 ? 'Waiting for the server' : '', [time]);
+
+  return (
+    <>
+      {!isReady && <Loading tagline={tagline} message={message} />}
+      <div className={isReady ? '' : classes.hidden}>
+        {children}
+      </div>
+    </>
+  );
+};
+
+
+export default DynoWaiter;
+
-- 
cgit v1.2.3

