From 3e6a9a9c6ade6cffe08b705e18bc5da437673ec4 Mon Sep 17 00:00:00 2001 From: gudnuf Date: Thu, 5 Mar 2026 14:28:24 -0800 Subject: [PATCH] Fix send and buy continue loading state across navigation --- app/features/buy/buy-input.tsx | 6 +++++- app/features/buy/buy-store.ts | 4 ++-- app/features/send/send-input.tsx | 6 +++++- app/features/send/send-store.ts | 4 ++-- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/app/features/buy/buy-input.tsx b/app/features/buy/buy-input.tsx index fe7fb36c..30197c37 100644 --- a/app/features/buy/buy-input.tsx +++ b/app/features/buy/buy-input.tsx @@ -1,3 +1,4 @@ +import { useState } from 'react'; import { MoneyInputDisplay } from '~/components/money-display'; import { Numpad } from '~/components/numpad'; import { @@ -36,6 +37,7 @@ export default function BuyInput() { const { redirectTo } = useRedirectTo('/'); const { animationClass: shakeAnimationClass, start: startShakeAnimation } = useAnimation({ name: 'shake' }); + const [isContinuing, setIsContinuing] = useState(false); const buyAccountId = useBuyStore((s) => s.accountId); const buyAccount = useAccount(buyAccountId); @@ -76,9 +78,11 @@ export default function BuyInput() { amount = convertedValue; } + setIsContinuing(true); const result = await getBuyQuote(amount); if (!result.success) { + setIsContinuing(false); if (result.error instanceof DomainError) { toast({ description: result.error.message }); } else { @@ -158,7 +162,7 @@ export default function BuyInput() { diff --git a/app/features/buy/buy-store.ts b/app/features/buy/buy-store.ts index 4a9ed120..3545c2fd 100644 --- a/app/features/buy/buy-store.ts +++ b/app/features/buy/buy-store.ts @@ -16,7 +16,7 @@ type GetBuyQuoteResult = | { success: false; error: unknown }; export type BuyState = { - status: 'idle' | 'quoting' | 'success'; + status: 'idle' | 'quoting'; /** The ID of the account to buy into */ accountId: string; /** The amount to buy */ @@ -92,7 +92,7 @@ export const createBuyStore = ({ }; } - set({ status: 'success', quote }); + set({ status: 'idle', quote }); return { success: true, quote }; } catch (error) { set({ status: 'idle' }); diff --git a/app/features/send/send-input.tsx b/app/features/send/send-input.tsx index cea77d45..348fb817 100644 --- a/app/features/send/send-input.tsx +++ b/app/features/send/send-input.tsx @@ -60,6 +60,7 @@ export function SendInput() { const { data: accounts } = useAccounts(); const [selectDestinationDrawerOpen, setSelectDestinationDrawerOpen] = useState(false); + const [isContinuing, setIsContinuing] = useState(false); const sendAmount = useSendStore((s) => s.amount); const sendAccount = useSendStore((s) => s.getSourceAccount()); @@ -103,8 +104,10 @@ export function SendInput() { return; } + setIsContinuing(true); const result = await continueSend(inputValue, convertedValue); if (!result.success) { + setIsContinuing(false); const toastOptions = result.error instanceof DomainError ? { description: result.error.message } @@ -123,6 +126,7 @@ export function SendInput() { if (result.next === 'selectDestination') { setSelectDestinationDrawerOpen(true); + setIsContinuing(false); return; } @@ -253,7 +257,7 @@ export function SendInput() { diff --git a/app/features/send/send-store.ts b/app/features/send/send-store.ts index d38af242..ef9e2dba 100644 --- a/app/features/send/send-store.ts +++ b/app/features/send/send-store.ts @@ -111,7 +111,7 @@ type DecodedDestination = { }; type State = { - status: 'idle' | 'quoting' | 'success'; + status: 'idle' | 'quoting'; /** * Amount to send. */ @@ -481,7 +481,7 @@ export const createSendStore = ({ } } - set({ status: 'success' }); + set({ status: 'idle' }); return { success: true, next: 'confirmQuote' }; }, };