fix: show preparation state for Money Account deposits cp-8.3.0#33325
fix: show preparation state for Money Account deposits cp-8.3.0#33325pedronfigueiredo wants to merge 18 commits into
Conversation
|
CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes. |
🧪 Flaky unit test detectionRun history flaky detectionHistorical failure rate is a hint, not proof — review each suggestion in context. See the flaky-test-detection skill for the full pattern reference and manual audit workflow. Failures / runs sampled per window:
AI-detected flaky patterns
|
|
| updateTokenAmount, | ||
| ]); | ||
|
|
||
| useEffect(() => { |
There was a problem hiding this comment.
Why do we need to wait for quote completion explicitly, can't we just immediately clear after the update in a finally block and the quote loading will already be triggered automatically and keep the skeletons visible?
| const [isKeyboardVisible, setIsKeyboardVisible] = useState( | ||
| !isAddMusdIntent && !isDepositPrefillEnabled, | ||
| ); | ||
| const [isPreparingQuote, setIsPreparingQuote] = useState(false); |
There was a problem hiding this comment.
Why do we need both state and a ref?
If we're setting state and are therefore happy with the re-render, what purpose does the ref serve?
There was a problem hiding this comment.
Kept the ref, but renamed it to isAmountUpdateInProgressRef. isPreparingQuote controls rendering, while the ref synchronously blocks a second Done press before React commits the state update. Added regression coverage that fires two presses in the same batch and verifies updateTokenAmount runs once. Addressed in bf771c752b.
| const [isKeyboardVisible, setIsKeyboardVisible] = useState( | ||
| !isAddMusdIntent && !isDepositPrefillEnabled, | ||
| ); | ||
| const [isPreparingQuote, setIsPreparingQuote] = useState(false); |
There was a problem hiding this comment.
Should we be explicit and call this isAmountUpdating for clarity?
| const isQuoteLoading = useIsTransactionPayQuoteLoading(); | ||
| const isQuotesLoading = useIsTransactionPayLoading(); | ||
| const showLoadingReview = isPreparingQuote || isQuotesLoading; | ||
| const showMoneyAccountLoadingReview = |
There was a problem hiding this comment.
Does this need to be type specific, won't this logic be applicable for any flow?
Ideally we minimise type specific logic here for simplicity sake.
| return; | ||
| } | ||
|
|
||
| if (isMoneyAccountDeposit) { |
There was a problem hiding this comment.
Can we apply this logic universally so immediately close keyboard always?
| } | ||
| onPress={handleAmountPress} | ||
| onPress={ | ||
| showMoneyAccountLoadingReview ? undefined : handleAmountPress |
There was a problem hiding this comment.
isAmountUpdating?
Won't impact other flows as they are synchronous.
There was a problem hiding this comment.
Already addressed in c21b192447: the shared render state is named isAmountUpdating and is used for all flows. Synchronous flows resolve it immediately, while asynchronous flows keep the loading state active. The focused tests cover both Money and non-Money updates.
| function ConfirmButton({ | ||
| alertTitle, | ||
| disableConfirm, | ||
| isLoadingReview, |
| !hideBuyForNoFunds && | ||
| !isDepositPrefillEnabled && <BuySection />} | ||
| {!isKeyboardVisible && ( | ||
| {(!isKeyboardVisible || showMoneyAccountLoadingReview) && ( |
There was a problem hiding this comment.
If we immediately hide the keyboard, why do we also need to check showMoneyAccountLoadingReview ?
| /> | ||
| )} | ||
| {isKeyboardVisible && | ||
| !showMoneyAccountLoadingReview && |
There was a problem hiding this comment.
Also here, ideally we minimise the criteria for these render conditions, so can't we rely on the existing isKeyboardVisible since we hide keyboard explicitly when starting update?
| @@ -375,7 +423,9 @@ | |||
| <PayWithRow isResultReady /> | |||
| )} | |||
| {!hasAccountNoFunds && | |||
There was a problem hiding this comment.
This JSX is quickly getting scary, could we make a Quote component in this file to handle the quote rows and skeletons? So we can early return and remove all these ternary statements?
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit f29e5ae. Configure here.
🔍 Smart E2E Test Selection
click to see 🤖 AI reasoning detailsE2E Test Selection: The PR introduces UX improvements to the custom amount entry flow used in Money (card/ramps) and Perps withdraw confirmations:
Affected flows:
The changes are medium risk - they modify UI state management logic in a shared component used across multiple flows, but the changes are well-scoped to the amount update loading state and don't touch core transaction submission logic. Performance Test Selection: |




Description
Money Account deposits could appear unresponsive for several seconds after the user pressed Continue because the amount-entry keypad remained visible while transaction calldata and quote prerequisites were prepared.
This change adds a local preparation state for Money Account deposits. It immediately replaces the keypad with the existing review-loading presentation, keeps the From and Pay with rows visible but non-interactive, disables amount editing and duplicate submission, and displays fee/time/total skeletons with a disabled Add funds button. The amount retains its normal visual emphasis while its edit action is unavailable. The same UI remains visible while TransactionPayController fetches quotes, and the amount, account, and payment token stay locked until quote loading settles. This avoids a perceived loading restart, stale review details, or an enabled-button flicker between the two phases.
If preparation fails, the amount-entry keypad is restored and the existing error toast is retained. Relay quote latency and quote failures remain separate from this local preparation state.
Changelog
CHANGELOG entry: Fixed missing loading feedback while Money Account deposits were being prepared
Related issues
Refs: #33317
Manual testing steps
Automated verification:
yarn jest app/components/Views/confirmations/components/info/custom-amount-info/custom-amount-info.test.tsx --runInBand --silentyarn lint:tscScreenshots/Recordings
Before
N/A — no simulator recording was captured for this code-only change.
After
N/A — the preparation transition is covered by targeted component unit tests.
Pre-merge author checklist
Performance checks (if applicable)
For performance guidelines and tooling, see the Performance Guide.
Pre-merge reviewer checklist
Note
Medium Risk
Touches confirmation UX and amount-commit/quote handoff timing for money deposits; regressions could affect button state, stale quotes, or non-money flows, though tests target those paths.
Overview
Money Account deposit Continue no longer leaves the amount keypad up while calldata and quotes are prepared. CustomAmountInfo now enters a local preparation / loading review as soon as Done runs: the keypad closes, fee/time/total skeletons show, From / Pay with stay visible but review rows use
pointerEvents: 'none', amount edit is blocked (with normal text styling), duplicate Done is guarded via a ref, and Add funds stays disabled through controller quote loading.Preparation ends when TransactionPay loading finishes or
quotesLastUpdatedchanges after the commit (newuseTransactionPayQuotesLastUpdatedselector/hook), with logic to ignore stale quote timestamps mid-commit and a zero-timeout handoff for synchronous updates. Failures reopen the keypad and keep the existing amount-update toast. Payment detail rendering is centralized in aQuotehelper;ConfirmButtonalso respectsisAmountUpdating.Coverage adds a Money Account quote preparation test block and related rerender helpers.
Reviewed by Cursor Bugbot for commit 43f430c. Bugbot is set up for automated code reviews on this repo. Configure here.