add isValidating behavior

This commit is contained in:
Matthias Kretschmann 2024-03-31 04:32:11 +01:00
parent 1aa4ee1afc
commit e5153b2730
Signed by: m
GPG Key ID: 606EEEF3C479A91F
10 changed files with 66 additions and 36 deletions

View File

@ -5,7 +5,7 @@ import styles from './CalculationBase.module.css'
import { usePrices } from '@/hooks'
export function CalculationBase() {
const prices = usePrices()
const { prices } = usePrices()
return (
<ul className={styles.calculationBase}>

View File

@ -13,7 +13,7 @@ export function FormAmount({
}: {
amount: number
setAmount: Dispatch<SetStateAction<number>>
token: Token
token: Token | string
setToken?: Dispatch<SetStateAction<Token>>
isFiat?: boolean
}) {

View File

@ -8,7 +8,7 @@ export function InputToken({
setToken,
isFiat
}: {
token: Token
token: Token | string
isFiat?: boolean
setToken?: Dispatch<SetStateAction<Token>>
}) {

View File

@ -1 +1 @@
export type Token = 'ocean' | 'fet' | 'agix' | 'usd' | undefined
export type Token = 'ocean' | 'fet' | 'agix' | undefined

View File

@ -56,3 +56,19 @@
filter: grayscale(1);
}
}
.isValidating {
animation: flicker 2s infinite ease-out forwards;
}
@keyframes flicker {
0% {
opacity: 0.25;
}
50% {
opacity: 1;
}
100% {
opacity: 0.25;
}
}

View File

@ -10,6 +10,7 @@ type Props = {
amountAsi: number
amountFiat: number
amountOriginalFiat?: number
isValidating: boolean
}
export function Result({
@ -18,11 +19,16 @@ export function Result({
amount,
amountAsi,
amountFiat,
amountOriginalFiat
amountOriginalFiat,
isValidating
}: Props) {
return (
<div className={styles.result}>
<div className={styles.resultLine}>
<div
className={`${styles.resultLine} ${
isValidating ? styles.isValidating : ''
}`}
>
<span className={styles.logo} data-symbol={tokenSymbol}>
<Image
src={`https://tokens.1inch.io/${tokenAddress}.png`}
@ -40,7 +46,11 @@ export function Result({
</span>
) : null}
</div>
<div className={styles.resultLine}>
<div
className={`${styles.resultLine} ${
isValidating ? styles.isValidating : ''
}`}
>
<ArrowRightIcon className={styles.iconArrow} />
<strong title={`${amountAsi}`}>
{formatNumber(amountAsi || 0, 'ASI')}

View File

@ -9,7 +9,7 @@ import { usePrices } from '@/hooks'
import { FormAmount } from '@/components/FormAmount'
export function Buy() {
const prices = usePrices()
const { prices, isValidating } = usePrices()
const [amount, setAmount] = useState(100)
const [debouncedAmount] = useDebounce(amount, 500)
@ -32,6 +32,7 @@ export function Buy() {
? (debouncedAmount / prices.ocean) * ratioOceanToAsi * prices.asi
: 0
}
isValidating={isValidating}
/>
<Result
tokenSymbol="AGIX"
@ -45,6 +46,7 @@ export function Buy() {
? (debouncedAmount / prices.agix) * ratioAgixToAsi * prices.asi
: 0
}
isValidating={isValidating}
/>
<Result
tokenSymbol="FET"
@ -58,6 +60,7 @@ export function Buy() {
? (debouncedAmount / prices.fet) * ratioFetToAsi * prices.asi
: 0
}
isValidating={isValidating}
/>
</div>
)

View File

@ -16,20 +16,22 @@ import { usePrices } from '@/hooks'
import { FormAmount, type Token } from '@/components/FormAmount'
export function Swap() {
const prices = usePrices()
const { prices, isValidating: isValidatingPrices } = usePrices()
const [amount, setAmount] = useState(100)
const [debouncedAmount] = useDebounce(amount, 500)
const [token, setToken] = useState<Token>('ocean')
const { data: dataSwapOceanToAgix } = useSWR(
`/api/quote/?tokenIn=${tokens[0]}&tokenOut=${tokens[2]}&amountIn=${debouncedAmount}`,
fetcher
)
const { data: dataSwapOceanToAgix, isValidating: isValidatingOceanToAgix } =
useSWR(
`/api/quote/?tokenIn=${tokens[0]}&tokenOut=${tokens[2]}&amountIn=${debouncedAmount}`,
fetcher
)
const { data: dataSwapOceanToFet } = useSWR(
`/api/quote/?tokenIn=${tokens[0]}&tokenOut=${tokens[1]}&amountIn=${debouncedAmount}`,
fetcher
)
const { data: dataSwapOceanToFet, isValidating: isValidatingOceanToFet } =
useSWR(
`/api/quote/?tokenIn=${tokens[0]}&tokenOut=${tokens[1]}&amountIn=${debouncedAmount}`,
fetcher
)
return (
<div className={stylesShared.results}>
@ -51,6 +53,11 @@ export function Swap() {
amountAsi={debouncedAmount * ratioOceanToAsi}
amountFiat={debouncedAmount * ratioOceanToAsi * prices.asi}
amountOriginalFiat={token ? debouncedAmount * prices[token] : undefined}
isValidating={
isValidatingOceanToAgix ||
isValidatingOceanToFet ||
isValidatingPrices
}
/>
<Result
@ -74,6 +81,7 @@ export function Swap() {
(dataSwapOceanToAgix?.amountOut /
Number(`1e${dataSwapOceanToAgix?.decimals}`) || 0) * prices.agix
}
isValidating={isValidatingOceanToAgix || isValidatingPrices}
/>
<Result
@ -95,6 +103,7 @@ export function Swap() {
(dataSwapOceanToFet?.amountOut /
Number(`1e${dataSwapOceanToFet?.decimals}`) || 0) * prices.asi
}
isValidating={isValidatingOceanToFet || isValidatingPrices}
/>
</div>
)

View File

@ -1,23 +1,12 @@
.results {
border: 1px solid rgba(var(--foreground-rgb), 0.2);
border-radius: var(--border-radius);
padding: 1.25rem 1.5rem;
padding: 1.5rem 2rem;
}
/* .results form {
border-color: transparent;
}
.results input {
background: none;
}
.results:hover form {
border-color: rgba(var(--foreground-rgb), 0.2);
} */
.title {
margin-bottom: 1.5rem;
font-size: 1.2rem;
color: rgb(var(--foreground-rgb-highlight));
min-height: 58px;
}

View File

@ -4,16 +4,19 @@ import { tokens } from '@/constants'
import { fetcher } from '@/utils'
import useSWR from 'swr'
export function usePrices(): { [key: string]: number } {
const { data: dataPrices } = useSWR(
export function usePrices(): {
prices: { ocean: number; fet: number; agix: number; asi: number }
isValidating: boolean
} {
const { data, isValidating } = useSWR(
`/api/prices/?tokens=${tokens.toString()}`,
fetcher
)
const ocean = dataPrices?.[tokens[0]]?.usd || 0
const fet = dataPrices?.[tokens[1]]?.usd || 0
const agix = dataPrices?.[tokens[2]]?.usd || 0
const ocean = data?.[tokens[0]]?.usd || 0
const fet = data?.[tokens[1]]?.usd || 0
const agix = data?.[tokens[2]]?.usd || 0
const asi = fet
return { ocean, fet, agix, asi }
return { prices: { ocean, fet, agix, asi }, isValidating }
}