fix: display updated widget token immediately (#5020)

* fix: display updated widget token immediately

* fix: disable if undefaulted

* docs: add comment
This commit is contained in:
Zach Pomerantz 2022-10-28 12:41:50 -07:00 committed by GitHub
parent aba6c1a1f4
commit 6712eafefe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -8,7 +8,12 @@ import { useCallback, useEffect, useMemo, useState } from 'react'
const EMPTY_AMOUNT = '' const EMPTY_AMOUNT = ''
type SwapValue = Required<SwapController>['value'] type SwapValue = Required<SwapController>['value']
type SwapTokens = Pick<SwapValue, Field.INPUT | Field.OUTPUT> type SwapTokens = Pick<SwapValue, Field.INPUT | Field.OUTPUT> & { default?: Currency }
function includesDefaultToken(tokens: SwapTokens) {
if (!tokens.default) return true
return tokens[Field.INPUT]?.equals(tokens.default) || tokens[Field.OUTPUT]?.equals(tokens.default)
}
/** /**
* Integrates the Widget's inputs. * Integrates the Widget's inputs.
@ -16,7 +21,7 @@ type SwapTokens = Pick<SwapValue, Field.INPUT | Field.OUTPUT>
* Enforces that token is a part of the returned value. * Enforces that token is a part of the returned value.
*/ */
export function useSyncWidgetInputs({ export function useSyncWidgetInputs({
token: defaultToken, token,
onTokenChange, onTokenChange,
}: { }: {
token?: Currency token?: Currency
@ -26,16 +31,17 @@ export function useSyncWidgetInputs({
const [type, setType] = useState<SwapValue['type']>(TradeType.EXACT_INPUT) const [type, setType] = useState<SwapValue['type']>(TradeType.EXACT_INPUT)
const [amount, setAmount] = useState<SwapValue['amount']>(EMPTY_AMOUNT) const [amount, setAmount] = useState<SwapValue['amount']>(EMPTY_AMOUNT)
const [tokens, setTokens] = useState<SwapTokens>({ [Field.OUTPUT]: defaultToken }) const [tokens, setTokens] = useState<SwapTokens>({ [Field.OUTPUT]: token, default: token })
const shouldDefault = useCallback( useEffect(() => {
(tokens: SwapTokens) => defaultToken && !Object.values(tokens).some((token) => token?.equals(defaultToken)), setTokens((tokens) => {
[defaultToken] const update = { ...tokens, default: token }
) if (!includesDefaultToken(update)) {
useEffect( return { [Field.OUTPUT]: update.default, default: update.default }
() => setTokens((tokens) => (shouldDefault(tokens) ? { [Field.OUTPUT]: defaultToken } : tokens)), }
[defaultToken, shouldDefault] return update
) })
}, [token])
const onAmountChange = useCallback( const onAmountChange = useCallback(
(field: Field, amount: string, origin?: 'max') => { (field: Field, amount: string, origin?: 'max') => {
@ -54,6 +60,7 @@ export function useSyncWidgetInputs({
setTokens((tokens) => ({ setTokens((tokens) => ({
[Field.INPUT]: tokens[Field.OUTPUT], [Field.INPUT]: tokens[Field.OUTPUT],
[Field.OUTPUT]: tokens[Field.INPUT], [Field.OUTPUT]: tokens[Field.INPUT],
default: tokens.default,
})) }))
}, [trace]) }, [trace])
@ -74,13 +81,14 @@ export function useSyncWidgetInputs({
const update = { const update = {
[selectingField]: token, [selectingField]: token,
[otherField]: otherToken, [otherField]: otherToken,
default: tokens.default,
} }
if (shouldDefault(update)) { if (!includesDefaultToken(update)) {
onTokenChange?.(update[Field.OUTPUT] || update[Field.INPUT] || token) onTokenChange?.(update[Field.OUTPUT] || update[Field.INPUT] || token)
} }
setTokens(update) setTokens(update)
}, },
[onTokenChange, selectingField, shouldDefault, tokens] [onTokenChange, selectingField, tokens]
) )
const tokenSelector = ( const tokenSelector = (
<CurrencySearchModal <CurrencySearchModal
@ -96,9 +104,11 @@ export function useSyncWidgetInputs({
() => ({ () => ({
type, type,
amount, amount,
...tokens, // If the default has not yet been handled, preemptively disable the widget by passing no tokens. Effectively,
// this resets the widget - avoiding rendering stale state - because with no tokens the skeleton will be rendered.
...(token && tokens.default?.equals(token) ? tokens : undefined),
}), }),
[amount, tokens, type] [amount, token, tokens, type]
) )
const valueHandlers: SwapEventHandlers = useMemo( const valueHandlers: SwapEventHandlers = useMemo(
() => ({ onAmountChange, onSwitchTokens, onTokenSelectorClick }), () => ({ onAmountChange, onSwitchTokens, onTokenSelectorClick }),