Commit d1627a6c authored by Jordan Frankfurt's avatar Jordan Frankfurt Committed by GitHub

fix(L2): remove redux from chain connectivity (#2781)

* remove redux from chain connectivity

* useMachineTimeMs instead of Date.now to force updates, useCurrentBlockTimestamp

* use useInterval
parent 55c97189
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 { useAppSelector } from 'state/hooks'
import { useBlockNumber } from 'state/application/hooks'
import styled, { keyframes } from 'styled-components/macro'
import { ExternalLink, TYPE } from 'theme'
import { ExplorerDataType, getExplorerLink } from 'utils/getExplorerLink'
import { useActiveWeb3React } from '../../hooks/web3'
import { useBlockNumber } from '../../state/application/hooks'
import { ExternalLink, TYPE } from '../../theme'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
import { ChainConnectivityWarning } from './ChainConnectivityWarning'
const StyledPolling = styled.div<{ warning: boolean }>`
......@@ -68,12 +71,21 @@ const Spinner = styled.div<{ warning: boolean }>`
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 chainConnectivityWarning = useAppSelector((state) => state.application.chainConnectivityWarning)
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(
() => {
......@@ -98,20 +110,14 @@ export default function Polling() {
<ExternalLink
href={chainId && blockNumber ? getExplorerLink(chainId, blockNumber.toString(), ExplorerDataType.BLOCK) : ''}
>
<StyledPolling
onMouseEnter={() => setIsHover(true)}
onMouseLeave={() => setIsHover(false)}
warning={chainConnectivityWarning}
>
<StyledPolling onMouseEnter={() => setIsHover(true)} onMouseLeave={() => setIsHover(false)} warning={warning}>
<StyledPollingNumber breathe={isMounting} hovering={isHover}>
{blockNumber}&ensp;
</StyledPollingNumber>
<StyledPollingDot warning={chainConnectivityWarning}>
{isMounting && <Spinner warning={chainConnectivityWarning} />}
</StyledPollingDot>{' '}
<StyledPollingDot warning={warning}>{isMounting && <Spinner warning={warning} />}</StyledPollingDot>{' '}
</StyledPolling>
</ExternalLink>
{chainConnectivityWarning && <ChainConnectivityWarning />}
{warning && <ChainConnectivityWarning />}
</>
)
}
......@@ -133,7 +133,7 @@ export const CHAIN_INFO: ChainInfo = {
nativeCurrency: { name: 'Görli ETH', symbol: 'görETH', decimals: 18 },
},
[SupportedChainId.OPTIMISM]: {
blockWaitMsBeforeWarning: ms`10m`,
blockWaitMsBeforeWarning: ms`15m`,
bridge: 'https://gateway.optimism.io/',
docs: 'https://optimism.io/',
explorer: 'https://optimistic.etherscan.io/',
......@@ -144,7 +144,7 @@ export const CHAIN_INFO: ChainInfo = {
rpcUrls: ['https://mainnet.optimism.io'],
},
[SupportedChainId.OPTIMISTIC_KOVAN]: {
blockWaitMsBeforeWarning: ms`10m`,
blockWaitMsBeforeWarning: ms`15m`,
bridge: 'https://gateway.optimism.io/',
docs: 'https://optimism.io/',
explorer: 'https://optimistic.etherscan.io/',
......
import { useState } from 'react'
import useInterval from './useInterval'
const useMachineTimeMs = (updateInterval: number): number => {
const [now, setNow] = useState(Date.now())
useInterval(() => {
setNow(Date.now())
}, updateInterval)
return now
}
export default useMachineTimeMs
......@@ -19,7 +19,6 @@ describe('application reducer', () => {
[1]: 3,
},
chainId: null,
chainConnectivityWarning: false,
implements3085: false,
openModal: null,
popupList: [],
......
......@@ -25,7 +25,6 @@ type PopupList = Array<{ key: string; show: boolean; content: PopupContent; remo
export interface ApplicationState {
readonly blockNumber: { readonly [chainId: number]: number }
readonly chainConnectivityWarning: boolean
readonly chainId: number | null
readonly implements3085: boolean
readonly openModal: ApplicationModal | null
......@@ -34,7 +33,6 @@ export interface ApplicationState {
const initialState: ApplicationState = {
blockNumber: {},
chainConnectivityWarning: false,
chainId: null,
implements3085: false,
openModal: null,
......@@ -80,19 +78,9 @@ const applicationSlice = createSlice({
setImplements3085(state, { payload: { implements3085 } }) {
state.implements3085 = implements3085
},
setChainConnectivityWarning(state, { payload: { warn } }) {
state.chainConnectivityWarning = warn
},
},
})
export const {
updateChainId,
updateBlockNumber,
setOpenModal,
addPopup,
removePopup,
setImplements3085,
setChainConnectivityWarning,
} = applicationSlice.actions
export const { updateChainId, updateBlockNumber, setOpenModal, addPopup, removePopup, setImplements3085 } =
applicationSlice.actions
export default applicationSlice.reducer
import { CHAIN_INFO } from 'constants/chains'
import useCurrentBlockTimestamp from 'hooks/useCurrentBlockTimestamp'
import useDebounce from 'hooks/useDebounce'
import useIsWindowVisible from 'hooks/useIsWindowVisible'
import { useActiveWeb3React } from 'hooks/web3'
import ms from 'ms.macro'
import { useCallback, useEffect, useRef, useState } from 'react'
import { useCallback, useEffect, useState } from 'react'
import { api, CHAIN_TAG } from 'state/data/enhanced'
import { useAppDispatch, useAppSelector } from 'state/hooks'
import { supportedChainId } from 'utils/supportedChainId'
import { switchToNetwork } from 'utils/switchToNetwork'
import { setChainConnectivityWarning, setImplements3085, updateBlockNumber, updateChainId } from './reducer'
import { setImplements3085, updateBlockNumber, updateChainId } from './reducer'
function useQueryCacheInvalidator() {
const dispatch = useAppDispatch()
......@@ -25,61 +22,6 @@ function useQueryCacheInvalidator() {
}, [chainId, dispatch])
}
const NETWORK_HEALTH_CHECK_MS = ms`15s`
const DEFAULT_MS_BEFORE_WARNING = ms`10m`
function useBlockWarningTimer() {
const { chainId } = useActiveWeb3React()
const dispatch = useAppDispatch()
const chainConnectivityWarningActive = useAppSelector((state) => state.application.chainConnectivityWarning)
const timeout = useRef<NodeJS.Timeout>()
const isWindowVisible = useIsWindowVisible()
const [msSinceLastBlock, setMsSinceLastBlock] = useState(0)
const blockTimestamp = useCurrentBlockTimestamp()
const waitMsBeforeWarning =
(chainId ? CHAIN_INFO[chainId]?.blockWaitMsBeforeWarning : DEFAULT_MS_BEFORE_WARNING) ?? DEFAULT_MS_BEFORE_WARNING
useEffect(() => {
if (blockTimestamp && chainId) {
if (Math.floor(Date.now() - blockTimestamp.mul(1000).toNumber()) > waitMsBeforeWarning) {
if (!chainConnectivityWarningActive) {
dispatch(setChainConnectivityWarning({ warn: true }))
}
} else {
if (chainConnectivityWarningActive) {
dispatch(setChainConnectivityWarning({ warn: false }))
}
}
}
}, [blockTimestamp, chainId, chainConnectivityWarningActive, dispatch, waitMsBeforeWarning])
useEffect(() => {
timeout.current = setTimeout(() => {
setMsSinceLastBlock(NETWORK_HEALTH_CHECK_MS + msSinceLastBlock)
if (msSinceLastBlock > waitMsBeforeWarning && isWindowVisible) {
dispatch(setChainConnectivityWarning({ warn: true }))
} else if (chainConnectivityWarningActive) {
dispatch(setChainConnectivityWarning({ warn: false }))
}
}, NETWORK_HEALTH_CHECK_MS)
return function cleanup() {
if (timeout.current) {
clearTimeout(timeout.current)
}
}
}, [
chainId,
chainConnectivityWarningActive,
dispatch,
isWindowVisible,
msSinceLastBlock,
setMsSinceLastBlock,
waitMsBeforeWarning,
])
}
export default function Updater(): null {
const { account, chainId, library } = useActiveWeb3React()
const dispatch = useAppDispatch()
......@@ -90,7 +32,6 @@ export default function Updater(): null {
blockNumber: null,
})
useBlockWarningTimer()
useQueryCacheInvalidator()
const blockNumberCallback = useCallback(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment