feat: swap form fixes & improvements (#322)
This commit is contained in:
parent
d4a2f19db2
commit
bb6a9b99e3
@ -4,16 +4,17 @@ import classNames from 'classnames'
|
|||||||
import InputOverlay from 'components/RangeInput/InputOverlay'
|
import InputOverlay from 'components/RangeInput/InputOverlay'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
value: number
|
|
||||||
onChange: (value: number) => void
|
|
||||||
wrapperClassName?: string
|
|
||||||
disabled?: boolean
|
|
||||||
max: number
|
max: number
|
||||||
|
value: number
|
||||||
|
disabled?: boolean
|
||||||
marginThreshold?: number
|
marginThreshold?: number
|
||||||
|
wrapperClassName?: string
|
||||||
|
onChange: (value: number) => void
|
||||||
|
onBlur?: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
function RangeInput(props: Props) {
|
function RangeInput(props: Props) {
|
||||||
const { value, max, onChange, wrapperClassName, disabled, marginThreshold } = props
|
const { value, max, onChange, wrapperClassName, disabled, marginThreshold, onBlur } = props
|
||||||
|
|
||||||
const handleOnChange = useCallback(
|
const handleOnChange = useCallback(
|
||||||
(event: ChangeEvent<HTMLInputElement>) => {
|
(event: ChangeEvent<HTMLInputElement>) => {
|
||||||
@ -36,6 +37,7 @@ function RangeInput(props: Props) {
|
|||||||
step={max / 100}
|
step={max / 100}
|
||||||
max={max}
|
max={max}
|
||||||
onChange={handleOnChange}
|
onChange={handleOnChange}
|
||||||
|
onBlur={onBlur}
|
||||||
/>
|
/>
|
||||||
<InputOverlay
|
<InputOverlay
|
||||||
max={max}
|
max={max}
|
||||||
|
@ -15,19 +15,21 @@ interface Props {
|
|||||||
containerClassName?: string
|
containerClassName?: string
|
||||||
setAmount: (amount: BigNumber) => void
|
setAmount: (amount: BigNumber) => void
|
||||||
onFocus?: () => void
|
onFocus?: () => void
|
||||||
|
onBlur?: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function AssetAmountInput(props: Props) {
|
export default function AssetAmountInput(props: Props) {
|
||||||
const {
|
const {
|
||||||
|
max,
|
||||||
label,
|
label,
|
||||||
amount,
|
amount,
|
||||||
setAmount,
|
|
||||||
asset,
|
asset,
|
||||||
containerClassName,
|
setAmount,
|
||||||
max,
|
|
||||||
maxButtonLabel,
|
|
||||||
onFocus,
|
|
||||||
assetUSDValue,
|
assetUSDValue,
|
||||||
|
maxButtonLabel,
|
||||||
|
containerClassName,
|
||||||
|
onFocus,
|
||||||
|
onBlur,
|
||||||
} = props
|
} = props
|
||||||
|
|
||||||
const handleMaxClick = useCallback(() => {
|
const handleMaxClick = useCallback(() => {
|
||||||
@ -52,6 +54,7 @@ export default function AssetAmountInput(props: Props) {
|
|||||||
max={max}
|
max={max}
|
||||||
onChange={setAmount}
|
onChange={setAmount}
|
||||||
onFocus={onFocus}
|
onFocus={onFocus}
|
||||||
|
onBlur={onBlur}
|
||||||
/>
|
/>
|
||||||
<span>{asset.symbol}</span>
|
<span>{asset.symbol}</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -30,10 +30,11 @@ export default function SwapForm(props: Props) {
|
|||||||
const account = useCurrentAccount()
|
const account = useCurrentAccount()
|
||||||
const { data: prices } = usePrices()
|
const { data: prices } = usePrices()
|
||||||
const swap = useStore((s) => s.swap)
|
const swap = useStore((s) => s.swap)
|
||||||
|
const [slippage] = useLocalStorage(SLIPPAGE_KEY, DEFAULT_SETTINGS.slippage)
|
||||||
|
|
||||||
const [isMarginChecked, setMarginChecked] = useState(false)
|
const [isMarginChecked, setMarginChecked] = useState(false)
|
||||||
const [buyAssetAmount, setBuyAssetAmount] = useState(BN_ZERO)
|
const [buyAssetAmount, setBuyAssetAmount] = useState(BN_ZERO)
|
||||||
const [sellAssetAmount, setSellAssetAmount] = useState(BN_ZERO)
|
const [sellAssetAmount, setSellAssetAmount] = useState(BN_ZERO)
|
||||||
const [slippage] = useLocalStorage(SLIPPAGE_KEY, DEFAULT_SETTINGS.slippage)
|
|
||||||
const [focusedInput, setFocusedInput] = useState<'buy' | 'sell' | null>(null)
|
const [focusedInput, setFocusedInput] = useState<'buy' | 'sell' | null>(null)
|
||||||
const [maxBuyableAmountEstimation, setMaxBuyableAmountEstimation] = useState(BN_ZERO)
|
const [maxBuyableAmountEstimation, setMaxBuyableAmountEstimation] = useState(BN_ZERO)
|
||||||
const [selectedOrderType, setSelectedOrderType] = useState<AvailableOrderType>('Market')
|
const [selectedOrderType, setSelectedOrderType] = useState<AvailableOrderType>('Market')
|
||||||
@ -43,13 +44,6 @@ export default function SwapForm(props: Props) {
|
|||||||
[account, sellAsset.denom],
|
[account, sellAsset.denom],
|
||||||
)
|
)
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
estimateExactIn(
|
|
||||||
{ denom: sellAsset.denom, amount: accountSellAssetDeposit },
|
|
||||||
buyAsset.denom,
|
|
||||||
).then(setMaxBuyableAmountEstimation)
|
|
||||||
}, [accountSellAssetDeposit, buyAsset.denom, sellAsset.denom])
|
|
||||||
|
|
||||||
const [buyAssetValue, sellAssetValue] = useMemo(() => {
|
const [buyAssetValue, sellAssetValue] = useMemo(() => {
|
||||||
const buyAssetPrice = prices.find(byDenom(buyAsset.denom))?.amount ?? BN_ZERO
|
const buyAssetPrice = prices.find(byDenom(buyAsset.denom))?.amount ?? BN_ZERO
|
||||||
const sellAssetPrice = prices.find(byDenom(sellAsset.denom))?.amount ?? BN_ZERO
|
const sellAssetPrice = prices.find(byDenom(sellAsset.denom))?.amount ?? BN_ZERO
|
||||||
@ -68,6 +62,19 @@ export default function SwapForm(props: Props) {
|
|||||||
sellAssetAmount,
|
sellAssetAmount,
|
||||||
])
|
])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setFocusedInput(null)
|
||||||
|
setBuyAssetAmount(BN_ZERO)
|
||||||
|
setSellAssetAmount(BN_ZERO)
|
||||||
|
}, [buyAsset.denom, sellAsset.denom])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
estimateExactIn(
|
||||||
|
{ denom: sellAsset.denom, amount: accountSellAssetDeposit },
|
||||||
|
buyAsset.denom,
|
||||||
|
).then(setMaxBuyableAmountEstimation)
|
||||||
|
}, [accountSellAssetDeposit, buyAsset.denom, sellAsset.denom])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (focusedInput === 'sell') {
|
if (focusedInput === 'sell') {
|
||||||
estimateExactIn(
|
estimateExactIn(
|
||||||
@ -89,16 +96,6 @@ export default function SwapForm(props: Props) {
|
|||||||
}
|
}
|
||||||
}, [buyAsset.denom, buyAssetAmount, focusedInput, sellAsset.denom])
|
}, [buyAsset.denom, buyAssetAmount, focusedInput, sellAsset.denom])
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setFocusedInput(null)
|
|
||||||
setBuyAssetAmount(BN_ZERO)
|
|
||||||
setSellAssetAmount(BN_ZERO)
|
|
||||||
}, [sellAsset.denom])
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setFocusedInput(null)
|
|
||||||
}, [buyAsset.denom])
|
|
||||||
|
|
||||||
const handleBuyClick = useCallback(async () => {
|
const handleBuyClick = useCallback(async () => {
|
||||||
if (account?.id) {
|
if (account?.id) {
|
||||||
const isSucceeded = await swap({
|
const isSucceeded = await swap({
|
||||||
@ -110,10 +107,20 @@ export default function SwapForm(props: Props) {
|
|||||||
})
|
})
|
||||||
if (isSucceeded) {
|
if (isSucceeded) {
|
||||||
setSellAssetAmount(BN_ZERO)
|
setSellAssetAmount(BN_ZERO)
|
||||||
|
setBuyAssetAmount(BN_ZERO)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [account?.id, buyAsset.denom, sellAsset.denom, sellAssetAmount, slippage, swap])
|
}, [account?.id, buyAsset.denom, sellAsset.denom, sellAssetAmount, slippage, swap])
|
||||||
|
|
||||||
|
const dismissInputFocus = useCallback(() => setFocusedInput(null), [])
|
||||||
|
const handleRangeInputChange = useCallback(
|
||||||
|
(value: number) => {
|
||||||
|
setFocusedInput('sell')
|
||||||
|
setSellAssetAmount(BN(value).shiftedBy(sellAsset.decimals).integerValue())
|
||||||
|
},
|
||||||
|
[sellAsset.decimals],
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Divider />
|
<Divider />
|
||||||
@ -131,16 +138,15 @@ export default function SwapForm(props: Props) {
|
|||||||
assetUSDValue={buyAssetValue}
|
assetUSDValue={buyAssetValue}
|
||||||
maxButtonLabel='Max Amount:'
|
maxButtonLabel='Max Amount:'
|
||||||
containerClassName='mx-3 my-6'
|
containerClassName='mx-3 my-6'
|
||||||
|
onBlur={dismissInputFocus}
|
||||||
onFocus={() => setFocusedInput('buy')}
|
onFocus={() => setFocusedInput('buy')}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<RangeInput
|
<RangeInput
|
||||||
max={accountSellAssetDeposit.shiftedBy(-sellAsset.decimals).toNumber()}
|
max={accountSellAssetDeposit.shiftedBy(-sellAsset.decimals).toNumber()}
|
||||||
value={sellAssetAmount.shiftedBy(-sellAsset.decimals).toNumber()}
|
value={sellAssetAmount.shiftedBy(-sellAsset.decimals).toNumber()}
|
||||||
onChange={(value) => {
|
onChange={handleRangeInputChange}
|
||||||
setFocusedInput('sell')
|
onBlur={dismissInputFocus}
|
||||||
setSellAssetAmount(BN(value).shiftedBy(sellAsset.decimals).integerValue())
|
|
||||||
}}
|
|
||||||
wrapperClassName='p-4'
|
wrapperClassName='p-4'
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@ -153,6 +159,7 @@ export default function SwapForm(props: Props) {
|
|||||||
asset={sellAsset}
|
asset={sellAsset}
|
||||||
maxButtonLabel='Balance:'
|
maxButtonLabel='Balance:'
|
||||||
containerClassName='mx-3'
|
containerClassName='mx-3'
|
||||||
|
onBlur={dismissInputFocus}
|
||||||
onFocus={() => setFocusedInput('sell')}
|
onFocus={() => setFocusedInput('sell')}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user