-
Notifications
You must be signed in to change notification settings - Fork 638
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Simplify SwapInputController animated reaction logic for responding to input value changes #5923
Changes from all commits
727efb0
2d859ee
add51f2
4bffe7c
6fdbbd4
2f5bd11
8570f1f
0261b63
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -547,64 +547,35 @@ export function useSwapInputsController({ | |
{ leading: false, trailing: true } | ||
); | ||
|
||
const onTypedNumber = useDebouncedCallback( | ||
(amount: number, inputKey: inputKeys, preserveAmount = true) => { | ||
lastTypedInput.value = inputKey; | ||
|
||
if (amount > 0) { | ||
const updateWorklet = () => { | ||
'worklet'; | ||
// If the user enters a new inputAmount, update the slider position ahead of the quote fetch, because | ||
// we can derive the slider position directly from the entered amount. | ||
if (inputKey === 'inputAmount') { | ||
const inputAssetBalance = internalSelectedInputAsset.value?.maxSwappableAmount || '0'; | ||
if (equalWorklet(inputAssetBalance, 0)) { | ||
sliderXPosition.value = withSpring(0, snappySpringConfig); | ||
} else { | ||
const updatedSliderPosition = clamp(Number(divWorklet(amount, inputAssetBalance)) * SLIDER_WIDTH, 0, SLIDER_WIDTH); | ||
sliderXPosition.value = withSpring(updatedSliderPosition, snappySpringConfig); | ||
} | ||
} | ||
fetchQuoteAndAssetPrices(); | ||
}; | ||
const resetValuesToZeroWorklet = (inputKey?: inputKeys) => { | ||
'worklet'; | ||
quoteFetchingInterval.stop(); | ||
if (isFetching.value) isFetching.value = false; | ||
if (isQuoteStale.value !== 0) isQuoteStale.value = 0; | ||
|
||
const resetValues = { | ||
inputAmount: 0, | ||
inputNativeValue: 0, | ||
outputAmount: 0, | ||
outputNativeValue: 0, | ||
}; | ||
|
||
if (!inputKey) { | ||
inputValues.modify(values => ({ ...values, ...resetValues })); | ||
return; | ||
} | ||
|
||
runOnUI(updateWorklet)(); | ||
} else { | ||
const resetValuesToZero = () => { | ||
if (isFetching.value) isFetching.value = false; | ||
if (isQuoteStale.value !== 0) isQuoteStale.value = 0; | ||
|
||
const updateWorklet = () => { | ||
'worklet'; | ||
const keysToReset = ['inputAmount', 'inputNativeValue', 'outputAmount', 'outputNativeValue']; | ||
const updatedValues = keysToReset.reduce( | ||
(acc, key) => { | ||
const castedKey = key as keyof typeof inputValues.value; | ||
acc[castedKey] = castedKey === inputKey && preserveAmount ? inputValues.value[castedKey] : 0; | ||
return acc; | ||
}, | ||
{} as Partial<typeof inputValues.value> | ||
); | ||
inputValues.modify(values => { | ||
return { | ||
...values, | ||
...updatedValues, | ||
}; | ||
}); | ||
sliderXPosition.value = withSpring(0, snappySpringConfig); | ||
isQuoteStale.value = 0; | ||
quoteFetchingInterval.stop(); | ||
}; | ||
const inputKeyValue = inputValues.value[inputKey]; | ||
const hasDecimal = inputKeyValue.toString().includes('.'); | ||
|
||
runOnUI(updateWorklet)(); | ||
}; | ||
inputValues.modify(values => ({ | ||
...values, | ||
...resetValues, | ||
[inputKey]: hasDecimal ? inputKeyValue : 0, | ||
})); | ||
|
||
resetValuesToZero(); | ||
} | ||
}, | ||
300, | ||
{ leading: false, trailing: true } | ||
); | ||
sliderXPosition.value = withSpring(0, snappySpringConfig); | ||
}; | ||
|
||
const debouncedFetchQuote = useDebouncedCallback( | ||
() => { | ||
|
@@ -695,20 +666,7 @@ export function useSwapInputsController({ | |
if (inputMethod.value === 'slider' && internalSelectedInputAsset.value && current.sliderXPosition !== previous.sliderXPosition) { | ||
// If the slider position changes | ||
if (percentageToSwap.value === 0) { | ||
// If the change set the slider position to 0 | ||
quoteFetchingInterval.stop(); | ||
isQuoteStale.value = 0; | ||
isFetching.value = false; | ||
|
||
inputValues.modify(values => { | ||
return { | ||
...values, | ||
inputAmount: 0, | ||
inputNativeValue: 0, | ||
outputAmount: 0, | ||
outputNativeValue: 0, | ||
}; | ||
}); | ||
resetValuesToZeroWorklet(); | ||
} else { | ||
// If the change set the slider position to > 0 | ||
if (!internalSelectedInputAsset.value) return; | ||
|
@@ -748,29 +706,10 @@ export function useSwapInputsController({ | |
} | ||
if (inputMethod.value === 'inputAmount' && !equalWorklet(current.values.inputAmount, previous.values.inputAmount)) { | ||
// If the number in the input field changes | ||
lastTypedInput.value = 'inputAmount'; | ||
if (equalWorklet(current.values.inputAmount, 0)) { | ||
// If the input amount was set to 0 | ||
quoteFetchingInterval.stop(); | ||
isQuoteStale.value = 0; | ||
isFetching.value = false; | ||
|
||
const hasDecimal = current.values.inputAmount.toString().includes('.'); | ||
|
||
sliderXPosition.value = withSpring(0, snappySpringConfig); | ||
inputValues.modify(values => { | ||
return { | ||
...values, | ||
inputAmount: hasDecimal ? current.values.inputAmount : 0, | ||
inputNativeValue: 0, | ||
outputAmount: 0, | ||
outputNativeValue: 0, | ||
}; | ||
}); | ||
if (hasDecimal) { | ||
runOnJS(onTypedNumber)(0, 'inputAmount', true); | ||
} else { | ||
runOnJS(onTypedNumber)(0, 'inputAmount'); | ||
} | ||
resetValuesToZeroWorklet('inputAmount'); | ||
} else { | ||
// If the input amount was set to a non-zero value | ||
if (!internalSelectedInputAsset.value) return; | ||
|
@@ -798,35 +737,15 @@ export function useSwapInputsController({ | |
sliderXPosition.value = withSpring(updatedSliderPosition, snappySpringConfig); | ||
} | ||
|
||
runOnJS(onTypedNumber)(Number(current.values.inputAmount), 'inputAmount', true); | ||
runOnJS(debouncedFetchQuote)(); | ||
} | ||
} | ||
if (inputMethod.value === 'outputAmount' && !equalWorklet(current.values.outputAmount, previous.values.outputAmount)) { | ||
// If the number in the output field changes | ||
lastTypedInput.value = 'outputAmount'; | ||
if (equalWorklet(current.values.outputAmount, 0)) { | ||
// If the output amount was set to 0 | ||
quoteFetchingInterval.stop(); | ||
isQuoteStale.value = 0; | ||
isFetching.value = false; | ||
|
||
const hasDecimal = current.values.outputAmount.toString().includes('.'); | ||
|
||
sliderXPosition.value = withSpring(0, snappySpringConfig); | ||
inputValues.modify(values => { | ||
return { | ||
...values, | ||
inputAmount: 0, | ||
inputNativeValue: 0, | ||
outputAmount: hasDecimal ? current.values.outputAmount : 0, | ||
outputNativeValue: 0, | ||
}; | ||
}); | ||
|
||
if (hasDecimal) { | ||
runOnJS(onTypedNumber)(0, 'outputAmount', true); | ||
} else { | ||
runOnJS(onTypedNumber)(0, 'outputAmount'); | ||
} | ||
resetValuesToZeroWorklet('outputAmount'); | ||
} else if (greaterThanWorklet(current.values.outputAmount, 0)) { | ||
// If the output amount was set to a non-zero value | ||
if (isQuoteStale.value !== 1) isQuoteStale.value = 1; | ||
|
@@ -840,7 +759,7 @@ export function useSwapInputsController({ | |
}; | ||
}); | ||
|
||
runOnJS(onTypedNumber)(Number(current.values.outputAmount), 'outputAmount'); | ||
runOnJS(debouncedFetchQuote)(); | ||
} | ||
} | ||
} | ||
|
@@ -913,25 +832,31 @@ export function useSwapInputsController({ | |
const inputNativePrice = internalSelectedInputAsset.value?.nativePrice || internalSelectedInputAsset.value?.price?.value || 0; | ||
const outputNativePrice = internalSelectedOutputAsset.value?.nativePrice || internalSelectedOutputAsset.value?.price?.value || 0; | ||
|
||
const prevInputNativeValue = inputValues.value.inputNativeValue; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pulling these variables out for readability as it can get confusing when you've flipped assets that the native price corresponds to the "new" input / output assets while the inputValues correspond to the previous input/output assets. |
||
const prevOutputAmount = inputValues.value.outputAmount; | ||
const newInputAmount = inputNativePrice > 0 ? divWorklet(prevInputNativeValue, inputNativePrice) : prevOutputAmount; | ||
|
||
const inputAmount = Number( | ||
valueBasedDecimalFormatter({ | ||
amount: | ||
inputNativePrice > 0 ? divWorklet(inputValues.value.inputNativeValue, inputNativePrice) : inputValues.value.outputAmount, | ||
amount: newInputAmount, | ||
nativePrice: inputNativePrice, | ||
roundingMode: 'up', | ||
isStablecoin: internalSelectedInputAsset.value?.type === 'stablecoin' ?? false, | ||
stripSeparators: true, | ||
}) | ||
); | ||
|
||
const prevOutputNativeValue = inputValues.value.outputNativeValue; | ||
const prevInputAmount = inputValues.value.inputAmount; | ||
const newOutputAmount = outputNativePrice > 0 ? divWorklet(prevOutputNativeValue, outputNativePrice) : prevInputAmount; | ||
|
||
inputValues.modify(values => { | ||
return { | ||
...values, | ||
inputAmount, | ||
inputNativeValue: inputValues.value.inputNativeValue, | ||
outputAmount: | ||
outputNativePrice > 0 ? divWorklet(inputValues.value.outputNativeValue, outputNativePrice) : inputValues.value.inputAmount, | ||
outputNativeValue: inputValues.value.outputNativeValue, | ||
inputNativeValue: mulWorklet(newInputAmount, inputNativePrice), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated |
||
outputAmount: newOutputAmount, | ||
outputNativeValue: mulWorklet(newOutputAmount, outputNativePrice), | ||
}; | ||
}); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code was only used for when the
inputKey
is theinputAmount
and is already done on lines 741-752 before the function is called, so it is redundant.