From 029780203ec8c75e7117cac1a406725996e23620 Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Tue, 4 Apr 2023 16:11:36 +0200 Subject: [PATCH] feat: convert inputValues to amounts and amounts to inputValues (#152) --- src/components/BorrowModal.tsx | 41 +++++++++++++++------------------- src/components/NumberInput.tsx | 32 +++++++++++++++++--------- src/components/TokenInput.tsx | 9 +++++--- 3 files changed, 46 insertions(+), 36 deletions(-) diff --git a/src/components/BorrowModal.tsx b/src/components/BorrowModal.tsx index 0f3df348..5177c10b 100644 --- a/src/components/BorrowModal.tsx +++ b/src/components/BorrowModal.tsx @@ -1,26 +1,26 @@ +import BigNumber from 'bignumber.js' import Image from 'next/image' import { useCallback, useState } from 'react' -import BigNumber from 'bignumber.js' -import { Modal } from 'components/Modal' -import TitleAndSubCell from 'components/TitleAndSubCell' -import useStore from 'store' -import { Text } from 'components/Text' -import { formatPercent, formatValue } from 'utils/formatters' -import Slider from 'components/Slider' import AccountSummary from 'components/Account/AccountSummary' +import { Button } from 'components/Button' import Card from 'components/Card' import Divider from 'components/Divider' -import TokenInput from 'components/TokenInput' -import { Button } from 'components/Button' import { ArrowRight } from 'components/Icons' +import { Modal } from 'components/Modal' +import Slider from 'components/Slider' +import { Text } from 'components/Text' +import TitleAndSubCell from 'components/TitleAndSubCell' +import TokenInput from 'components/TokenInput' import useParams from 'hooks/useParams' +import useStore from 'store' import { hardcodedFee } from 'utils/contants' +import { formatPercent, formatValue } from 'utils/formatters' export default function BorrowModal() { const params = useParams() const [percentage, setPercentage] = useState(0) - const [value, setValue] = useState(0) + const [amount, setAmount] = useState(0) const [selectedAccount, setSelectedAccount] = useState(params.account) const modal = useStore((s) => s.borrowModal) const borrow = useStore((s) => s.borrow) @@ -33,15 +33,12 @@ export default function BorrowModal() { function setOpen(isOpen: boolean) { useStore.setState({ borrowModal: null }) - setValue(0) + setAmount(0) setPercentage(0) } function onConfirmClick() { if (!modal?.asset) return - - const amount = new BigNumber(value).shiftedBy(modal.asset.decimals) - if (modal.isRepay) { repay({ fee: hardcodedFee, @@ -63,16 +60,16 @@ export default function BorrowModal() { (percentage: number, maxAmount: number) => { const amount = new BigNumber(percentage).div(100).times(maxAmount).toNumber() - setValue(amount) + setAmount(amount) setPercentage(percentage) }, [modal?.asset.decimals], ) const onInputChange = useCallback( - (value: number, maxAmount: number) => { - setValue(value) - setPercentage(new BigNumber(value).div(maxAmount).times(100).toNumber()) + (amount: number, maxAmount: number) => { + setAmount(amount) + setPercentage(new BigNumber(amount).div(maxAmount).times(100).toNumber()) }, [modal?.asset.decimals], ) @@ -96,9 +93,7 @@ export default function BorrowModal() { if ((modal.marketData as BorrowAssetActive)?.debt) debtAmount = Number((modal.marketData as BorrowAssetActive).debt) - const maxAmount = new BigNumber(modal.isRepay ? debtAmount : liquidityAmount) - .shiftedBy(-modal.asset.decimals) - .toNumber() + const maxAmount = modal.isRepay ? debtAmount : liquidityAmount return ( onInputChange(value, maxAmount)} - value={value} + onChange={(amount) => onInputChange(amount, maxAmount)} + amount={amount} max={maxAmount} /> onSliderChange(value, maxAmount)} /> diff --git a/src/components/NumberInput.tsx b/src/components/NumberInput.tsx index 531398e7..40d67c91 100644 --- a/src/components/NumberInput.tsx +++ b/src/components/NumberInput.tsx @@ -1,10 +1,12 @@ 'use client' +import BigNumber from 'bignumber.js' import classNames from 'classnames' import React, { useEffect, useState } from 'react' interface Props { - value: string + asset: Asset + amount: number className: string maxDecimals: number minValue?: number @@ -12,26 +14,36 @@ interface Props { maxLength?: number allowNegative?: boolean style?: {} - onChange: (value: number) => void + onChange: (amount: number) => void onBlur?: () => void onFocus?: () => void onRef?: (ref: React.RefObject) => void } +function magnify(value: number, asset: Asset) { + return value === 0 ? 0 : new BigNumber(value).shiftedBy(asset.decimals).toNumber() +} + +function demagnify(amount: number, asset: Asset) { + return amount === 0 ? 0 : new BigNumber(amount).dividedBy(10 ** asset.decimals).toNumber() +} + export default function NumberInput(props: Props) { const inputRef = React.useRef(null) const cursorRef = React.useRef(0) + const max = props.max ? demagnify(props.max, props.asset) : undefined + const [inputValue, setInputValue] = useState({ - formatted: props.value, - value: Number(props.value), + formatted: demagnify(props.amount, props.asset).toString(), + value: demagnify(props.amount, props.asset), }) useEffect(() => { setInputValue({ - formatted: props.value, - value: Number(props.value), + formatted: demagnify(props.amount, props.asset).toString(), + value: demagnify(props.amount, props.asset), }) - }, [props.value]) + }, [props.amount]) useEffect(() => { if (!props.onRef) return @@ -53,7 +65,7 @@ export default function NumberInput(props: Props) { } setInputValue({ formatted, value }) if (value !== inputValue.value) { - props.onChange(value) + props.onChange(magnify(value, props.asset)) } } @@ -80,7 +92,7 @@ export default function NumberInput(props: Props) { const isSeparator = lastChar === '.' || lastChar === ',' const isNegative = value.indexOf('-') > -1 const isLowerThanMinimum = props.minValue !== undefined && Number(value) < props.minValue - const isHigherThanMaximum = props.max !== undefined && Number(value) > props.max + const isHigherThanMaximum = max !== undefined && Number(value) > max const isTooLong = props.maxLength !== undefined && numberCount > props.maxLength const exceedsMaxDecimals = props.maxDecimals !== undefined && decimals > props.maxDecimals @@ -110,7 +122,7 @@ export default function NumberInput(props: Props) { } if (isHigherThanMaximum) { - updateValues(String(props.max), props.max!) + updateValues(String(max), max!) return } diff --git a/src/components/TokenInput.tsx b/src/components/TokenInput.tsx index 80621055..da94304e 100644 --- a/src/components/TokenInput.tsx +++ b/src/components/TokenInput.tsx @@ -1,13 +1,15 @@ import Image from 'next/image' +import BigNumber from 'bignumber.js' import NumberInput from 'components/NumberInput' import { Text } from 'components/Text' +import { useState } from 'react' interface Props { - value: number + amount: number max: number asset: Asset - onChange: (value: number) => void + onChange: (amount: number) => void } export default function TokenInput(props: Props) { @@ -19,9 +21,10 @@ export default function TokenInput(props: Props) { {props.asset.symbol}