aboutsummaryrefslogtreecommitdiffhomepage
path: root/app/src/Common/Loader.js
blob: d54580cfa38c20e3831ac82f61ee78038c4ba9a9 (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
import PropTypes from 'prop-types'
import { useEffect, useMemo, useState } from 'react'

import Modal from './Modal'
import Spinner from './Spinner'

function Loader(props) {
  const { load, delay, children } = props
  const [state, setState] = useState({
    loaded: false,
    delayed: false,
    timeout: null
  })

  useEffect(() => {
    clearTimeout(state.timeout)
    if (!load) {
      return
    }

    const timeout = setTimeout(() => {
      if (!state.loaded) {
        setState({ ...state, timeout: null, delayed: true })
      }
    }, delay)

    setState({
      loaded: false,
      delayed: false,
      timeout
    })

    load().then(() => {
      clearTimeout(timeout)
      setState({ ...state, timeout: null, loaded: true })
    })
  }, [load])

  if (state.loaded) {
    return <>{children}</>
  } else if (!state.delayed) {
    return null
  }

  return (
    <Modal>
      <Spinner style={{ color: 'white' }}>
        <p>Waiting for API...</p>
      </Spinner>
    </Modal>
  )
}

Loader.propTypes = {
  load: PropTypes.func.isRequired,
  inline: PropTypes.bool,
  delay: PropTypes.number,
}

Loader.defaultProps = {
  inline: false,
  delay: 200
}

export default Loader