feat: swap form fixes & improvements (#322)

This commit is contained in:
Yusuf Seyrek 2023-07-26 14:55:30 +03:00 committed by GitHub
parent d4a2f19db2
commit bb6a9b99e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 32 deletions

View File

@ -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}

View File

@ -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>

View File

@ -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')}
/> />