add countdown to refetch and refetch button

This commit is contained in:
saml33 2023-10-28 22:49:46 +11:00
parent 03fe88f012
commit 726863e053
5 changed files with 134 additions and 11 deletions

View File

@ -0,0 +1,49 @@
type CircularProgressProps = {
className?: string
size: number
progress: number
trackWidth: number
indicatorWidth: number
}
const CircularProgress = ({
className,
indicatorWidth,
progress,
size,
trackWidth,
}: CircularProgressProps) => {
const center = size / 2,
radius =
center - (trackWidth > indicatorWidth ? trackWidth : indicatorWidth),
dashArray = 2 * Math.PI * radius,
dashOffset = dashArray * ((100 - progress) / 100)
return (
<>
<div
className={`relative ${className}`}
style={{ width: size, height: size }}
>
<svg
className="-rotate-90 fill-transparent stroke-th-fgd-4"
style={{ width: size, height: size }}
>
<circle cx={center} cy={center} r={radius} strokeWidth={trackWidth} />
<circle
className="fill-transparent stroke-th-active"
cx={center}
cy={center}
r={radius}
strokeDasharray={dashArray}
strokeDashoffset={dashOffset}
strokeLinecap="round"
strokeWidth={indicatorWidth}
/>
</svg>
</div>
</>
)
}
export default CircularProgress

View File

@ -81,7 +81,11 @@ const MarketSwapForm = ({
const { mangoAccount } = useMangoAccount()
const quoteAmount =
swapMode === 'ExactIn' ? amountInFormValue : amountOutFormValue
const { bestRoute } = useQuoteRoutes({
const {
bestRoute,
isFetching: fetchingRoute,
refetch: refetchRoute,
} = useQuoteRoutes({
inputMint: inputBank?.mint.toString(),
outputMint: outputBank?.mint.toString(),
amount: quoteAmount,
@ -296,8 +300,10 @@ const MarketSwapForm = ({
<>
<SwapReviewRouteInfo
amountIn={amountInAsDecimal}
loadingRoute={fetchingRoute}
onClose={() => setShowConfirm(false)}
onSuccess={onSuccess}
refetchRoute={refetchRoute}
routes={bestRoute ? [bestRoute] : undefined}
selectedRoute={selectedRoute}
setSelectedRoute={setSelectedRoute}

View File

@ -27,6 +27,7 @@ import {
ArrowsRightLeftIcon,
ArrowRightIcon,
ChevronDownIcon,
ArrowPathIcon,
} from '@heroicons/react/20/solid'
import { useTranslation } from 'next-i18next'
import { formatNumericValue } from '../../utils/numbers'
@ -54,14 +55,28 @@ import {
TransactionErrors,
parseTxForKnownErrors,
} from '@blockworks-foundation/mango-v4'
import CircularProgress from '@components/shared/CircularProgress'
import {
QueryObserverResult,
RefetchOptions,
RefetchQueryFilters,
} from '@tanstack/react-query'
const set = mangoStore.getState().set
type JupiterRouteInfoProps = {
amountIn: Decimal
loadingRoute: boolean
isWalletSwap?: boolean
onClose: () => void
onSuccess?: () => void
refetchRoute:
| (<TPageData>(
options?: (RefetchOptions & RefetchQueryFilters<TPageData>) | undefined,
) => Promise<
QueryObserverResult<{ bestRoute: JupiterV6RouteInfo | null }, Error>
>)
| undefined
routes: JupiterV6RouteInfo[] | undefined
selectedRoute: JupiterV6RouteInfo | undefined | null
setSelectedRoute: Dispatch<
@ -217,9 +232,11 @@ const successSound = new Howl({
const SwapReviewRouteInfo = ({
amountIn,
loadingRoute,
isWalletSwap,
onClose,
onSuccess,
refetchRoute,
routes,
selectedRoute,
setSelectedRoute,
@ -243,6 +260,22 @@ const SwapReviewRouteInfo = ({
)
const focusRef = useRef<HTMLButtonElement>(null)
const [refetchRoutePercentage, setRefetchRoutePercentage] = useState(0)
useEffect(() => {
let currentPercentage = 0
const countdownInterval = setInterval(() => {
if (currentPercentage < 100) {
currentPercentage += 5 // 5% increment per second
setRefetchRoutePercentage(currentPercentage)
}
}, 1000)
return () => {
clearInterval(countdownInterval)
}
}, [selectedRoute])
const amountOut = useMemo(() => {
if (!selectedRoute?.outAmount || !outputTokenInfo) return
return new Decimal(selectedRoute.outAmount.toString()).div(
@ -489,15 +522,40 @@ const SwapReviewRouteInfo = ({
>
<div className="thin-scroll flex h-full flex-col justify-between overflow-y-auto">
<div>
<IconButton
className="absolute left-4 top-4 mr-3 text-th-fgd-2"
onClick={onClose}
size="small"
ref={focusRef}
>
<ArrowLeftIcon className="h-5 w-5" />
</IconButton>
<div className="flex justify-center bg-th-bkg-1 p-6 pb-0">
<div className="flex items-center justify-between px-4 pt-4">
<IconButton
className="text-th-fgd-2"
onClick={onClose}
size="small"
ref={focusRef}
>
<ArrowLeftIcon className="h-5 w-5" />
</IconButton>
<div className="relative h-8 w-8">
<CircularProgress
size={32}
indicatorWidth={1}
trackWidth={1}
progress={refetchRoutePercentage}
/>
{refetchRoute ? (
<IconButton
className="absolute bottom-0 left-0 right-0 top-0 text-th-fgd-2"
hideBg
onClick={() => refetchRoute()}
size="small"
ref={focusRef}
>
<ArrowPathIcon
className={`h-5 w-5 ${
loadingRoute ? 'animate-spin' : null
}`}
/>
</IconButton>
) : null}
</div>
</div>
<div className="flex justify-center bg-th-bkg-1 px-6 pt-2">
<div className="mb-3 flex w-full flex-col items-center border-b border-th-bkg-3 pb-4">
<div className="relative mb-2 w-[72px]">
<TokenLogo bank={inputBank} size={40} />

View File

@ -63,7 +63,11 @@ const WalletSwapForm = ({ setShowTokenSelect }: WalletSwapFormProps) => {
const { connected, publicKey } = useWallet()
const quoteAmount =
swapMode === 'ExactIn' ? amountInFormValue : amountOutFormValue
const { bestRoute } = useQuoteRoutes({
const {
bestRoute,
isFetching: fetchingRoute,
refetch: refetchRoute,
} = useQuoteRoutes({
inputMint: inputBank?.mint.toString(),
outputMint: outputBank?.mint.toString(),
amount: quoteAmount,
@ -298,8 +302,10 @@ const WalletSwapForm = ({ setShowTokenSelect }: WalletSwapFormProps) => {
<>
<SwapReviewRouteInfo
amountIn={amountInAsDecimal}
loadingRoute={fetchingRoute}
isWalletSwap
onClose={() => setShowConfirm(false)}
refetchRoute={refetchRoute}
routes={bestRoute ? [bestRoute] : undefined}
selectedRoute={selectedRoute}
setSelectedRoute={setSelectedRoute}

View File

@ -256,14 +256,18 @@ const useQuoteRoutes = ({
routes: [],
bestRoute: undefined,
}),
isFetching: res.isFetching,
isLoading: res.isLoading,
isInitialLoading: res.isInitialLoading,
refetch: res.refetch,
}
: {
routes: [],
bestRoute: undefined,
isFetching: false,
isLoading: false,
isInitialLoading: false,
refetch: undefined,
}
}