aboutsummaryrefslogtreecommitdiff
path: root/src/containers/Page/DynoWaiter.tsx
blob: 92255da6468a5f187ed4869dd3f9630846434cd4 (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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
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';
import EmptyState from '../../components/EmptyState/EmptyState';

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.',
  'We love you <3',
  'Almost done.'
];

const useStyles = makeStyles(theme => ({
  root: {
    textAlign: 'center'
  },
  hidden: {
    visibility: 'hidden',
    position: 'absolute',
    width: 0,
    height: 0,
    overflow: 'hidden'
  },
  img: {
    width: theme.spacing(24)
  }
}));

// TODO: if Dyno is sleeping, use this time to pre-load pages

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]);

  return (
    <>
      {!isReady && (
        <>
          <Loading />
          {message && <EmptyState variant="waiting" smart message={message} />}
        </>
      )}
      <div className={isReady ? '' : classes.hidden}>
        {children}
      </div>
    </>
  );
};


export default DynoWaiter;