chore: paint currency selector on initialization (#2245)

Avoids a flash of "Select a token" as the App initializes.
This commit is contained in:
Zach Pomerantz 2021-09-02 10:57:01 -07:00 committed by GitHub
parent 4bdf3c191a
commit f59c5f6877
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 33 additions and 24 deletions

@ -53,7 +53,8 @@ const Container = styled.div<{ hideInput: boolean }>`
}
`
const CurrencySelect = styled(ButtonGray)<{ selected: boolean; hideInput?: boolean }>`
const CurrencySelect = styled(ButtonGray)<{ visible: boolean; selected: boolean; hideInput?: boolean }>`
visibility: ${({ visible }) => (visible ? 'visible' : 'hidden')};
align-items: center;
font-size: 24px;
font-weight: 500;
@ -211,6 +212,7 @@ export default function CurrencyInputPanel({
<Container hideInput={hideInput}>
<InputRow style={hideInput ? { padding: '0', borderRadius: '8px' } : {}} selected={!onCurrencySelect}>
<CurrencySelect
visible={currency !== null}
selected={!!currency}
hideInput={hideInput}
className="open-currency-select-button"

@ -30,7 +30,7 @@ export default function CurrencyLogo({
style,
...rest
}: {
currency?: Currency
currency?: Currency | null
size?: string
style?: React.CSSProperties
}) {

@ -43,7 +43,7 @@ export default function UnsupportedCurrencyFooter({
currencies,
}: {
show: boolean
currencies: (Currency | undefined)[]
currencies: (Currency | undefined | null)[]
}) {
const { chainId } = useActiveWeb3React()
const [showDetails, setShowDetails] = useState(false)

@ -123,9 +123,9 @@ function parseStringOrBytes32(str: string | undefined, bytes32: string | undefin
}
// undefined if invalid or does not exist
// null if loading
// null if loading or null was passed
// otherwise returns the token
export function useToken(tokenAddress?: string): Token | undefined | null {
export function useToken(tokenAddress?: string | null): Token | undefined | null {
const { chainId } = useActiveWeb3React()
const tokens = useAllTokens()
@ -148,6 +148,7 @@ export function useToken(tokenAddress?: string): Token | undefined | null {
return useMemo(() => {
if (token) return token
if (tokenAddress === null) return null
if (!chainId || !address) return undefined
if (decimals.loading || symbol.loading || tokenName.loading) return null
if (decimals.result) {
@ -169,13 +170,14 @@ export function useToken(tokenAddress?: string): Token | undefined | null {
symbol.result,
symbolBytes32.result,
token,
tokenAddress,
tokenName.loading,
tokenName.result,
tokenNameBytes32.result,
])
}
export function useCurrency(currencyId: string | undefined): Currency | null | undefined {
export function useCurrency(currencyId: string | null | undefined): Currency | null | undefined {
const { chainId } = useActiveWeb3React()
const isETH = currencyId?.toUpperCase() === 'ETH'
const token = useToken(isETH ? undefined : currencyId)

@ -7,7 +7,7 @@ import { useUnsupportedTokens } from './Tokens'
* @param currencyIn the input currency to check
* @param currencyOut the output currency to check
*/
export function useIsSwapUnsupported(currencyIn?: Currency, currencyOut?: Currency): boolean {
export function useIsSwapUnsupported(currencyIn?: Currency | null, currencyOut?: Currency | null): boolean {
const unsupportedTokens: { [address: string]: Token } = useUnsupportedTokens()
return useMemo(() => {

@ -21,15 +21,15 @@ const NOT_APPLICABLE = { wrapType: WrapType.NOT_APPLICABLE }
* @param typedValue the user input value
*/
export default function useWrapCallback(
inputCurrency: Currency | undefined,
outputCurrency: Currency | undefined,
inputCurrency: Currency | undefined | null,
outputCurrency: Currency | undefined | null,
typedValue: string | undefined
): { wrapType: WrapType; execute?: undefined | (() => Promise<void>); inputError?: string } {
const { chainId, account } = useActiveWeb3React()
const wethContract = useWETHContract()
const balance = useCurrencyBalance(account ?? undefined, inputCurrency)
const balance = useCurrencyBalance(account ?? undefined, inputCurrency ?? undefined)
// we can always parse the amount typed as the input currency, since wrapping is 1:1
const inputAmount = useMemo(() => tryParseAmount(typedValue, inputCurrency), [inputCurrency, typedValue])
const inputAmount = useMemo(() => tryParseAmount(typedValue, inputCurrency ?? undefined), [inputCurrency, typedValue])
const addTransaction = useTransactionAdder()
return useMemo(() => {

@ -345,7 +345,7 @@ export default function Swap({ history }: RouteComponentProps) {
[onCurrencySelection]
)
const swapIsUnsupported = useIsSwapUnsupported(currencies?.INPUT, currencies?.OUTPUT)
const swapIsUnsupported = useIsSwapUnsupported(currencies[Field.INPUT], currencies[Field.OUTPUT])
const priceImpactTooHigh = priceImpactSeverity > 3 && !isExpertMode
@ -660,7 +660,10 @@ export default function Swap({ history }: RouteComponentProps) {
</AppBody>
<SwitchLocaleLink />
{!swapIsUnsupported ? null : (
<UnsupportedCurrencyFooter show={swapIsUnsupported} currencies={[currencies.INPUT, currencies.OUTPUT]} />
<UnsupportedCurrencyFooter
show={swapIsUnsupported}
currencies={[currencies[Field.INPUT], currencies[Field.OUTPUT]]}
/>
)}
</>
)

@ -115,7 +115,7 @@ function involvesAddress(
// from the current swap inputs, compute the best trade and return it.
export function useDerivedSwapInfo(toggledVersion: Version): {
currencies: { [field in Field]?: Currency }
currencies: { [field in Field]?: Currency | null }
currencyBalances: { [field in Field]?: CurrencyAmount<Currency> }
parsedAmount: CurrencyAmount<Currency> | undefined
inputError?: string
@ -167,9 +167,9 @@ export function useDerivedSwapInfo(toggledVersion: Version): {
[Field.OUTPUT]: relevantTokenBalances[1],
}
const currencies: { [field in Field]?: Currency } = {
[Field.INPUT]: inputCurrency ?? undefined,
[Field.OUTPUT]: outputCurrency ?? undefined,
const currencies: { [field in Field]?: Currency | null } = {
[Field.INPUT]: inputCurrency,
[Field.OUTPUT]: outputCurrency,
}
let inputError: string | undefined
@ -287,18 +287,20 @@ export function useDefaultsFromURLSearch():
useEffect(() => {
if (!chainId) return
const parsed = queryParametersToSwapState(parsedQs)
const inputCurrencyId = parsed[Field.INPUT].currencyId ?? undefined
const outputCurrencyId = parsed[Field.OUTPUT].currencyId ?? undefined
dispatch(
replaceSwapState({
typedValue: parsed.typedValue,
field: parsed.independentField,
inputCurrencyId: parsed[Field.INPUT].currencyId,
outputCurrencyId: parsed[Field.OUTPUT].currencyId,
inputCurrencyId,
outputCurrencyId,
recipient: parsed.recipient,
})
)
setResult({ inputCurrencyId: parsed[Field.INPUT].currencyId, outputCurrencyId: parsed[Field.OUTPUT].currencyId })
setResult({ inputCurrencyId, outputCurrencyId })
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [dispatch, chainId])

@ -5,10 +5,10 @@ export interface SwapState {
readonly independentField: Field
readonly typedValue: string
readonly [Field.INPUT]: {
readonly currencyId: string | undefined
readonly currencyId: string | undefined | null
}
readonly [Field.OUTPUT]: {
readonly currencyId: string | undefined
readonly currencyId: string | undefined | null
}
// the typed recipient address or ENS name, or null if swap should go to sender
readonly recipient: string | null
@ -18,10 +18,10 @@ const initialState: SwapState = {
independentField: Field.INPUT,
typedValue: '',
[Field.INPUT]: {
currencyId: '',
currencyId: null,
},
[Field.OUTPUT]: {
currencyId: '',
currencyId: null,
},
recipient: null,
}