2019-05-16 20:21:14 +03:00
|
|
|
import { useState, useMemo, useCallback, useEffect } from 'react'
|
2019-04-25 19:12:47 +03:00
|
|
|
import { useWeb3Context } from 'web3-react'
|
|
|
|
|
2019-05-30 23:42:25 +03:00
|
|
|
import ERC20_ABI from '../constants/abis/erc20'
|
|
|
|
import { getContract, getFactoryContract, getExchangeContract, isAddress } from '../utils'
|
|
|
|
import copy from 'copy-to-clipboard'
|
2019-04-25 19:12:47 +03:00
|
|
|
|
2019-05-16 20:21:14 +03:00
|
|
|
// modified from https://usehooks.com/useDebounce/
|
|
|
|
export function useDebounce(value, delay) {
|
|
|
|
const [debouncedValue, setDebouncedValue] = useState(value)
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
// Update debounced value after delay
|
|
|
|
const handler = setTimeout(() => {
|
|
|
|
setDebouncedValue(value)
|
|
|
|
}, delay)
|
|
|
|
|
|
|
|
// Cancel the timeout if value changes (also on delay change or unmount)
|
|
|
|
// This is how we prevent debounced value from updating if value is changed ...
|
|
|
|
// .. within the delay period. Timeout gets cleared and restarted.
|
|
|
|
return () => {
|
|
|
|
clearTimeout(handler)
|
|
|
|
}
|
|
|
|
}, [value, delay])
|
|
|
|
|
|
|
|
return debouncedValue
|
|
|
|
}
|
|
|
|
|
2019-05-03 23:37:59 +03:00
|
|
|
// modified from https://usehooks.com/useKeyPress/
|
|
|
|
export function useBodyKeyDown(targetKey, onKeyDown, suppressOnKeyDown = false) {
|
|
|
|
const downHandler = useCallback(
|
2019-05-30 23:42:25 +03:00
|
|
|
event => {
|
|
|
|
const {
|
|
|
|
target: { tagName },
|
|
|
|
key
|
|
|
|
} = event
|
2019-05-03 23:37:59 +03:00
|
|
|
if (key === targetKey && tagName === 'BODY' && !suppressOnKeyDown) {
|
2019-05-30 23:42:25 +03:00
|
|
|
event.preventDefault()
|
2019-05-03 23:37:59 +03:00
|
|
|
onKeyDown()
|
|
|
|
}
|
|
|
|
},
|
|
|
|
[targetKey, onKeyDown, suppressOnKeyDown]
|
|
|
|
)
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
window.addEventListener('keydown', downHandler)
|
|
|
|
return () => {
|
|
|
|
window.removeEventListener('keydown', downHandler)
|
|
|
|
}
|
|
|
|
}, [downHandler])
|
2019-04-25 19:12:47 +03:00
|
|
|
}
|
|
|
|
|
2019-05-30 23:42:25 +03:00
|
|
|
export function useENSName(address) {
|
|
|
|
const { library } = useWeb3Context()
|
|
|
|
|
|
|
|
const [ENSName, setENSNname] = useState()
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if (isAddress(address)) {
|
|
|
|
let stale = false
|
2019-07-30 01:34:15 +03:00
|
|
|
try {
|
|
|
|
library.lookupAddress(address).then(name => {
|
2019-05-30 23:42:25 +03:00
|
|
|
if (!stale) {
|
|
|
|
if (name) {
|
|
|
|
setENSNname(name)
|
|
|
|
} else {
|
|
|
|
setENSNname(null)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
2019-07-30 01:34:15 +03:00
|
|
|
} catch {
|
|
|
|
if (!stale) {
|
|
|
|
setENSNname(null)
|
|
|
|
}
|
|
|
|
}
|
2019-05-30 23:42:25 +03:00
|
|
|
|
|
|
|
return () => {
|
|
|
|
stale = true
|
|
|
|
setENSNname()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}, [library, address])
|
|
|
|
|
|
|
|
return ENSName
|
|
|
|
}
|
|
|
|
|
2019-05-03 23:37:59 +03:00
|
|
|
// returns null on errors
|
|
|
|
export function useContract(address, ABI, withSignerIfPossible = true) {
|
|
|
|
const { library, account } = useWeb3Context()
|
2019-04-25 19:12:47 +03:00
|
|
|
|
|
|
|
return useMemo(() => {
|
|
|
|
try {
|
2019-05-03 23:37:59 +03:00
|
|
|
return getContract(address, ABI, library, withSignerIfPossible ? account : undefined)
|
2019-04-25 19:12:47 +03:00
|
|
|
} catch {
|
|
|
|
return null
|
|
|
|
}
|
2019-05-03 23:37:59 +03:00
|
|
|
}, [address, ABI, library, withSignerIfPossible, account])
|
2019-04-25 19:12:47 +03:00
|
|
|
}
|
|
|
|
|
2019-05-03 23:37:59 +03:00
|
|
|
// returns null on errors
|
|
|
|
export function useTokenContract(tokenAddress, withSignerIfPossible = true) {
|
|
|
|
const { library, account } = useWeb3Context()
|
2019-04-25 19:12:47 +03:00
|
|
|
|
2019-05-03 23:37:59 +03:00
|
|
|
return useMemo(() => {
|
|
|
|
try {
|
|
|
|
return getContract(tokenAddress, ERC20_ABI, library, withSignerIfPossible ? account : undefined)
|
|
|
|
} catch {
|
|
|
|
return null
|
|
|
|
}
|
|
|
|
}, [tokenAddress, library, withSignerIfPossible, account])
|
2019-04-25 19:12:47 +03:00
|
|
|
}
|
|
|
|
|
2019-05-03 23:37:59 +03:00
|
|
|
// returns null on errors
|
|
|
|
export function useFactoryContract(withSignerIfPossible = true) {
|
|
|
|
const { networkId, library, account } = useWeb3Context()
|
|
|
|
|
|
|
|
return useMemo(() => {
|
|
|
|
try {
|
|
|
|
return getFactoryContract(networkId, library, withSignerIfPossible ? account : undefined)
|
|
|
|
} catch {
|
|
|
|
return null
|
2019-04-25 19:12:47 +03:00
|
|
|
}
|
2019-05-03 23:37:59 +03:00
|
|
|
}, [networkId, library, withSignerIfPossible, account])
|
|
|
|
}
|
2019-04-25 19:12:47 +03:00
|
|
|
|
2019-05-03 23:37:59 +03:00
|
|
|
export function useExchangeContract(exchangeAddress, withSignerIfPossible = true) {
|
|
|
|
const { library, account } = useWeb3Context()
|
|
|
|
|
|
|
|
return useMemo(() => {
|
|
|
|
try {
|
|
|
|
return getExchangeContract(exchangeAddress, library, withSignerIfPossible ? account : undefined)
|
|
|
|
} catch {
|
|
|
|
return null
|
2019-04-25 19:12:47 +03:00
|
|
|
}
|
2019-05-03 23:37:59 +03:00
|
|
|
}, [exchangeAddress, library, withSignerIfPossible, account])
|
2019-04-25 19:12:47 +03:00
|
|
|
}
|
2019-05-30 23:42:25 +03:00
|
|
|
|
|
|
|
export function useCopyClipboard(timeout = 500) {
|
|
|
|
const [isCopied, setIsCopied] = useState(false)
|
|
|
|
|
|
|
|
const staticCopy = useCallback(text => {
|
|
|
|
const didCopy = copy(text)
|
|
|
|
setIsCopied(didCopy)
|
|
|
|
}, [])
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if (isCopied) {
|
|
|
|
const hide = setTimeout(() => {
|
|
|
|
setIsCopied(false)
|
|
|
|
}, timeout)
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
clearTimeout(hide)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}, [isCopied, setIsCopied, timeout])
|
|
|
|
|
|
|
|
return [isCopied, staticCopy]
|
|
|
|
}
|