Commit f59c5f68 authored by Zach Pomerantz's avatar Zach Pomerantz Committed by GitHub

chore: paint currency selector on initialization (#2245)

Avoids a flash of "Select a token" as the App initializes.
parent 4bdf3c19
...@@ -53,7 +53,8 @@ const Container = styled.div<{ hideInput: boolean }>` ...@@ -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; align-items: center;
font-size: 24px; font-size: 24px;
font-weight: 500; font-weight: 500;
...@@ -211,6 +212,7 @@ export default function CurrencyInputPanel({ ...@@ -211,6 +212,7 @@ export default function CurrencyInputPanel({
<Container hideInput={hideInput}> <Container hideInput={hideInput}>
<InputRow style={hideInput ? { padding: '0', borderRadius: '8px' } : {}} selected={!onCurrencySelect}> <InputRow style={hideInput ? { padding: '0', borderRadius: '8px' } : {}} selected={!onCurrencySelect}>
<CurrencySelect <CurrencySelect
visible={currency !== null}
selected={!!currency} selected={!!currency}
hideInput={hideInput} hideInput={hideInput}
className="open-currency-select-button" className="open-currency-select-button"
......
...@@ -30,7 +30,7 @@ export default function CurrencyLogo({ ...@@ -30,7 +30,7 @@ export default function CurrencyLogo({
style, style,
...rest ...rest
}: { }: {
currency?: Currency currency?: Currency | null
size?: string size?: string
style?: React.CSSProperties style?: React.CSSProperties
}) { }) {
......
...@@ -43,7 +43,7 @@ export default function UnsupportedCurrencyFooter({ ...@@ -43,7 +43,7 @@ export default function UnsupportedCurrencyFooter({
currencies, currencies,
}: { }: {
show: boolean show: boolean
currencies: (Currency | undefined)[] currencies: (Currency | undefined | null)[]
}) { }) {
const { chainId } = useActiveWeb3React() const { chainId } = useActiveWeb3React()
const [showDetails, setShowDetails] = useState(false) const [showDetails, setShowDetails] = useState(false)
......
...@@ -123,9 +123,9 @@ function parseStringOrBytes32(str: string | undefined, bytes32: string | undefin ...@@ -123,9 +123,9 @@ function parseStringOrBytes32(str: string | undefined, bytes32: string | undefin
} }
// undefined if invalid or does not exist // undefined if invalid or does not exist
// null if loading // null if loading or null was passed
// otherwise returns the token // 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 { chainId } = useActiveWeb3React()
const tokens = useAllTokens() const tokens = useAllTokens()
...@@ -148,6 +148,7 @@ export function useToken(tokenAddress?: string): Token | undefined | null { ...@@ -148,6 +148,7 @@ export function useToken(tokenAddress?: string): Token | undefined | null {
return useMemo(() => { return useMemo(() => {
if (token) return token if (token) return token
if (tokenAddress === null) return null
if (!chainId || !address) return undefined if (!chainId || !address) return undefined
if (decimals.loading || symbol.loading || tokenName.loading) return null if (decimals.loading || symbol.loading || tokenName.loading) return null
if (decimals.result) { if (decimals.result) {
...@@ -169,13 +170,14 @@ export function useToken(tokenAddress?: string): Token | undefined | null { ...@@ -169,13 +170,14 @@ export function useToken(tokenAddress?: string): Token | undefined | null {
symbol.result, symbol.result,
symbolBytes32.result, symbolBytes32.result,
token, token,
tokenAddress,
tokenName.loading, tokenName.loading,
tokenName.result, tokenName.result,
tokenNameBytes32.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 { chainId } = useActiveWeb3React()
const isETH = currencyId?.toUpperCase() === 'ETH' const isETH = currencyId?.toUpperCase() === 'ETH'
const token = useToken(isETH ? undefined : currencyId) const token = useToken(isETH ? undefined : currencyId)
......
...@@ -7,7 +7,7 @@ import { useUnsupportedTokens } from './Tokens' ...@@ -7,7 +7,7 @@ import { useUnsupportedTokens } from './Tokens'
* @param currencyIn the input currency to check * @param currencyIn the input currency to check
* @param currencyOut the output 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() const unsupportedTokens: { [address: string]: Token } = useUnsupportedTokens()
return useMemo(() => { return useMemo(() => {
......
...@@ -21,15 +21,15 @@ const NOT_APPLICABLE = { wrapType: WrapType.NOT_APPLICABLE } ...@@ -21,15 +21,15 @@ const NOT_APPLICABLE = { wrapType: WrapType.NOT_APPLICABLE }
* @param typedValue the user input value * @param typedValue the user input value
*/ */
export default function useWrapCallback( export default function useWrapCallback(
inputCurrency: Currency | undefined, inputCurrency: Currency | undefined | null,
outputCurrency: Currency | undefined, outputCurrency: Currency | undefined | null,
typedValue: string | undefined typedValue: string | undefined
): { wrapType: WrapType; execute?: undefined | (() => Promise<void>); inputError?: string } { ): { wrapType: WrapType; execute?: undefined | (() => Promise<void>); inputError?: string } {
const { chainId, account } = useActiveWeb3React() const { chainId, account } = useActiveWeb3React()
const wethContract = useWETHContract() 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 // 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() const addTransaction = useTransactionAdder()
return useMemo(() => { return useMemo(() => {
......
...@@ -345,7 +345,7 @@ export default function Swap({ history }: RouteComponentProps) { ...@@ -345,7 +345,7 @@ export default function Swap({ history }: RouteComponentProps) {
[onCurrencySelection] [onCurrencySelection]
) )
const swapIsUnsupported = useIsSwapUnsupported(currencies?.INPUT, currencies?.OUTPUT) const swapIsUnsupported = useIsSwapUnsupported(currencies[Field.INPUT], currencies[Field.OUTPUT])
const priceImpactTooHigh = priceImpactSeverity > 3 && !isExpertMode const priceImpactTooHigh = priceImpactSeverity > 3 && !isExpertMode
...@@ -660,7 +660,10 @@ export default function Swap({ history }: RouteComponentProps) { ...@@ -660,7 +660,10 @@ export default function Swap({ history }: RouteComponentProps) {
</AppBody> </AppBody>
<SwitchLocaleLink /> <SwitchLocaleLink />
{!swapIsUnsupported ? null : ( {!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( ...@@ -115,7 +115,7 @@ function involvesAddress(
// from the current swap inputs, compute the best trade and return it. // from the current swap inputs, compute the best trade and return it.
export function useDerivedSwapInfo(toggledVersion: Version): { export function useDerivedSwapInfo(toggledVersion: Version): {
currencies: { [field in Field]?: Currency } currencies: { [field in Field]?: Currency | null }
currencyBalances: { [field in Field]?: CurrencyAmount<Currency> } currencyBalances: { [field in Field]?: CurrencyAmount<Currency> }
parsedAmount: CurrencyAmount<Currency> | undefined parsedAmount: CurrencyAmount<Currency> | undefined
inputError?: string inputError?: string
...@@ -167,9 +167,9 @@ export function useDerivedSwapInfo(toggledVersion: Version): { ...@@ -167,9 +167,9 @@ export function useDerivedSwapInfo(toggledVersion: Version): {
[Field.OUTPUT]: relevantTokenBalances[1], [Field.OUTPUT]: relevantTokenBalances[1],
} }
const currencies: { [field in Field]?: Currency } = { const currencies: { [field in Field]?: Currency | null } = {
[Field.INPUT]: inputCurrency ?? undefined, [Field.INPUT]: inputCurrency,
[Field.OUTPUT]: outputCurrency ?? undefined, [Field.OUTPUT]: outputCurrency,
} }
let inputError: string | undefined let inputError: string | undefined
...@@ -287,18 +287,20 @@ export function useDefaultsFromURLSearch(): ...@@ -287,18 +287,20 @@ export function useDefaultsFromURLSearch():
useEffect(() => { useEffect(() => {
if (!chainId) return if (!chainId) return
const parsed = queryParametersToSwapState(parsedQs) const parsed = queryParametersToSwapState(parsedQs)
const inputCurrencyId = parsed[Field.INPUT].currencyId ?? undefined
const outputCurrencyId = parsed[Field.OUTPUT].currencyId ?? undefined
dispatch( dispatch(
replaceSwapState({ replaceSwapState({
typedValue: parsed.typedValue, typedValue: parsed.typedValue,
field: parsed.independentField, field: parsed.independentField,
inputCurrencyId: parsed[Field.INPUT].currencyId, inputCurrencyId,
outputCurrencyId: parsed[Field.OUTPUT].currencyId, outputCurrencyId,
recipient: parsed.recipient, 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 // eslint-disable-next-line react-hooks/exhaustive-deps
}, [dispatch, chainId]) }, [dispatch, chainId])
......
...@@ -5,10 +5,10 @@ export interface SwapState { ...@@ -5,10 +5,10 @@ export interface SwapState {
readonly independentField: Field readonly independentField: Field
readonly typedValue: string readonly typedValue: string
readonly [Field.INPUT]: { readonly [Field.INPUT]: {
readonly currencyId: string | undefined readonly currencyId: string | undefined | null
} }
readonly [Field.OUTPUT]: { 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 // the typed recipient address or ENS name, or null if swap should go to sender
readonly recipient: string | null readonly recipient: string | null
...@@ -18,10 +18,10 @@ const initialState: SwapState = { ...@@ -18,10 +18,10 @@ const initialState: SwapState = {
independentField: Field.INPUT, independentField: Field.INPUT,
typedValue: '', typedValue: '',
[Field.INPUT]: { [Field.INPUT]: {
currencyId: '', currencyId: null,
}, },
[Field.OUTPUT]: { [Field.OUTPUT]: {
currencyId: '', currencyId: null,
}, },
recipient: null, recipient: null,
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment