forked from Uniswap/interface
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPolling.tsx
123 lines (108 loc) · 3.88 KB
/
Polling.tsx
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import { CHAIN_INFO } from 'constants/chains'
import useCurrentBlockTimestamp from 'hooks/useCurrentBlockTimestamp'
import useMachineTimeMs from 'hooks/useMachineTime'
import { useActiveWeb3React } from 'hooks/web3'
import ms from 'ms.macro'
import { useEffect, useState } from 'react'
import { useBlockNumber } from 'state/application/hooks'
import styled, { keyframes } from 'styled-components/macro'
import { ExternalLink, ThemedText } from 'theme'
import { ExplorerDataType, getExplorerLink } from 'utils/getExplorerLink'
import { ChainConnectivityWarning } from './ChainConnectivityWarning'
const StyledPolling = styled.div<{ warning: boolean }>`
position: fixed;
display: flex;
align-items: center;
right: 0;
bottom: 0;
padding: 1rem;
color: ${({ theme, warning }) => (warning ? theme.yellow3 : theme.green1)};
transition: 250ms ease color;
${({ theme }) => theme.mediaWidth.upToMedium`
display: none;
`}
`
const StyledPollingNumber = styled(ThemedText.Small)<{ breathe: boolean; hovering: boolean }>`
transition: opacity 0.25s ease;
opacity: ${({ breathe, hovering }) => (hovering ? 0.7 : breathe ? 1 : 0.5)};
:hover {
opacity: 1;
}
`
const StyledPollingDot = styled.div<{ warning: boolean }>`
width: 8px;
height: 8px;
min-height: 8px;
min-width: 8px;
border-radius: 50%;
position: relative;
background-color: ${({ theme, warning }) => (warning ? theme.yellow3 : theme.green1)};
transition: 250ms ease background-color;
`
const rotate360 = keyframes`
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
`
const Spinner = styled.div<{ warning: boolean }>`
animation: ${rotate360} 1s cubic-bezier(0.83, 0, 0.17, 1) infinite;
transform: translateZ(0);
border-top: 1px solid transparent;
border-right: 1px solid transparent;
border-bottom: 1px solid transparent;
border-left: 2px solid ${({ theme, warning }) => (warning ? theme.yellow3 : theme.green1)};
background: transparent;
width: 14px;
height: 14px;
border-radius: 50%;
position: relative;
transition: 250ms ease border-color;
left: -3px;
top: -3px;
`
const DEFAULT_MS_BEFORE_WARNING = ms`10m`
const NETWORK_HEALTH_CHECK_MS = ms`10s`
export default function Polling() {
const { chainId } = useActiveWeb3React()
const blockNumber = useBlockNumber()
const [isMounting, setIsMounting] = useState(false)
const [isHover, setIsHover] = useState(false)
const machineTime = useMachineTimeMs(NETWORK_HEALTH_CHECK_MS)
const blockTime = useCurrentBlockTimestamp()
const waitMsBeforeWarning =
(chainId ? CHAIN_INFO[chainId]?.blockWaitMsBeforeWarning : DEFAULT_MS_BEFORE_WARNING) ?? DEFAULT_MS_BEFORE_WARNING
const warning = Boolean(!!blockTime && machineTime - blockTime.mul(1000).toNumber() > waitMsBeforeWarning)
useEffect(
() => {
if (!blockNumber) {
return
}
setIsMounting(true)
const mountingTimer = setTimeout(() => setIsMounting(false), 1000)
// this will clear Timeout when component unmount like in willComponentUnmount
return () => {
clearTimeout(mountingTimer)
}
},
[blockNumber] //useEffect will run only one time
//if you pass a value to array, like this [data] than clearTimeout will run every time this value changes (useEffect re-run)
)
return (
<>
<ExternalLink
href={chainId && blockNumber ? getExplorerLink(chainId, blockNumber.toString(), ExplorerDataType.BLOCK) : ''}
>
<StyledPolling onMouseEnter={() => setIsHover(true)} onMouseLeave={() => setIsHover(false)} warning={warning}>
<StyledPollingNumber breathe={isMounting} hovering={isHover}>
{blockNumber} 
</StyledPollingNumber>
<StyledPollingDot warning={warning}>{isMounting && <Spinner warning={warning} />}</StyledPollingDot>{' '}
</StyledPolling>
</ExternalLink>
{warning && <ChainConnectivityWarning />}
</>
)
}