aboutsummaryrefslogtreecommitdiff
path: root/src/containers/Page/DynoWaiter.tsx
blob: d8460bfaca1e3e1b9d4ca7be3cb73edf73e14e58 (plain)
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
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;