Commit a11c7e95 authored by Jack Short's avatar Jack Short Committed by GitHub

feat: select input token for pay with any token (#5865)

* feat: select input token for pay with any token

* creating zustand state

* updating symbol

* cursor pointer
parent 31bbcae1
......@@ -3,6 +3,7 @@ import { parseEther } from '@ethersproject/units'
import { Trans } from '@lingui/macro'
import { TraceEvent } from '@uniswap/analytics'
import { BrowserEvent, InterfaceElementName, NFTEventName } from '@uniswap/analytics-events'
import { Currency } from '@uniswap/sdk-core'
import { useWeb3React } from '@web3-react/core'
import Column from 'components/Column'
import Loader from 'components/Loader'
......@@ -12,6 +13,7 @@ import { SupportedChainId } from 'constants/chains'
import { PayWithAnyTokenVariant, usePayWithAnyTokenFlag } from 'featureFlags/flags/payWithAnyToken'
import { useCurrency } from 'hooks/Tokens'
import { useBag } from 'nft/hooks/useBag'
import { useTokenInput } from 'nft/hooks/useTokenInput'
import { useWalletBalance } from 'nft/hooks/useWalletBalance'
import { BagStatus } from 'nft/types'
import { ethNumberStandardFormatter, formatWeiToDecimal } from 'nft/utils'
......@@ -141,7 +143,9 @@ export const BagFooter = ({
const { account, chainId, connector } = useWeb3React()
const connected = Boolean(account && chainId)
const shouldUsePayWithAnyToken = usePayWithAnyTokenFlag() === PayWithAnyTokenVariant.Enabled
const inputCurrency = useCurrency('ETH')
const inputCurrency = useTokenInput((state) => state.inputCurrency)
const setInputCurrency = useTokenInput((state) => state.setInputCurrency)
const defaultCurrency = useCurrency('ETH')
const setBagExpanded = useBag((state) => state.setBagExpanded)
const [showTokenSelector, toggleTokenSelector] = useReducer((state) => !state, false)
......@@ -193,6 +197,7 @@ export const BagFooter = ({
}, [bagStatus, chainId, connected, connector, fetchAssets, setBagExpanded, sufficientBalance, toggleWalletModal])
const isPending = PENDING_BAG_STATUSES.includes(bagStatus)
const activeCurrency = inputCurrency ?? defaultCurrency
return (
<FooterContainer>
......@@ -204,9 +209,9 @@ export const BagFooter = ({
<Trans>Pay with</Trans>
</ThemedText.SubHeaderSmall>
<CurrencyInput onClick={toggleTokenSelector}>
<CurrencyLogo currency={inputCurrency} size="24px" />
<CurrencyLogo currency={activeCurrency} size="24px" />
<ThemedText.HeadlineSmall fontWeight={500} lineHeight="24px">
{inputCurrency?.symbol}
{activeCurrency?.symbol}
</ThemedText.HeadlineSmall>
<ChevronDown size={20} color={theme.textSecondary} />
</CurrencyInput>
......@@ -216,7 +221,7 @@ export const BagFooter = ({
<Trans>Total</Trans>
</ThemedText.SubHeaderSmall>
<ThemedText.HeadlineSmall>
{formatWeiToDecimal(totalEthPrice.toString())}&nbsp;ETH
{formatWeiToDecimal(totalEthPrice.toString())}&nbsp;{activeCurrency?.symbol ?? 'ETH'}
</ThemedText.HeadlineSmall>
<ThemedText.BodySmall color="textSecondary" lineHeight="20px">{`${ethNumberStandardFormatter(
totalUsdPrice,
......@@ -259,7 +264,16 @@ export const BagFooter = ({
</ActionButton>
</TraceEvent>
</Footer>
{showTokenSelector && <BagTokenSelectorModal overlayClick={toggleTokenSelector} />}
{showTokenSelector && (
<BagTokenSelectorModal
selectedCurrency={activeCurrency ?? undefined}
handleCurrencySelect={(currency: Currency) => {
setInputCurrency(currency)
toggleTokenSelector()
}}
overlayClick={toggleTokenSelector}
/>
)}
</FooterContainer>
)
}
......@@ -47,7 +47,17 @@ const TokenSelectorContainer = styled(Column)`
}
`
export const BagTokenSelectorModal = ({ overlayClick }: { overlayClick: () => void }) => {
interface BagTokenSelectorModalProps {
selectedCurrency: Currency | undefined
handleCurrencySelect: (currency: Currency) => void
overlayClick: () => void
}
export const BagTokenSelectorModal = ({
selectedCurrency,
handleCurrencySelect,
overlayClick,
}: BagTokenSelectorModalProps) => {
const defaultTokens = useAllTokens()
const [balances, balancesAreLoading] = useAllTokenBalances()
const sortedTokens: Token[] = useMemo(
......@@ -90,7 +100,16 @@ export const BagTokenSelectorModal = ({ overlayClick }: { overlayClick: () => vo
</TitleRow>
<TokenSelectorContainer>
{currencies.map((currency) => {
return <CurrencyRow key={currency.isToken ? currency.wrapped.address : currency.name} currency={currency} />
return (
<CurrencyRow
key={currency.isToken ? currency.wrapped.address : currency.name}
currency={currency}
selected={
(!selectedCurrency && currency.isNative) || (!!selectedCurrency && selectedCurrency.equals(currency))
}
selectCurrency={handleCurrencySelect}
/>
)
})}
</TokenSelectorContainer>
</ModalWrapper>
......
......@@ -4,12 +4,15 @@ import Column from 'components/Column'
import CurrencyLogo from 'components/Logo/CurrencyLogo'
import Row from 'components/Row'
import useCurrencyBalance from 'lib/hooks/useCurrencyBalance'
import { Check } from 'react-feather'
import styled from 'styled-components/macro'
import { ThemedText } from 'theme'
const TokenRow = styled(Row)`
padding: 8px 0px;
gap: 12px;
justify-content: space-between;
cursor: pointer;
`
const TokenInfoRow = styled(Row)`
......@@ -24,12 +27,23 @@ const StyledBalanceText = styled(ThemedText.SubHeader)`
text-align: right;
`
export const CurrencyRow = ({ currency }: { currency: Currency }) => {
const StyledCheck = styled(Check)`
color: ${({ theme }) => theme.accentAction};
flex-shrink: 0;
`
interface CurrencyRowProps {
currency: Currency
selected: boolean
selectCurrency: (currency: Currency) => void
}
export const CurrencyRow = ({ currency, selected, selectCurrency }: CurrencyRowProps) => {
const { account } = useWeb3React()
const balance = useCurrencyBalance(account ?? undefined, currency)
return (
<TokenRow>
<TokenRow onClick={() => selectCurrency(currency)}>
<TokenInfoRow>
<CurrencyLogo currency={currency} size="36px" />
<Column>
......@@ -42,6 +56,7 @@ export const CurrencyRow = ({ currency }: { currency: Currency }) => {
</Column>
</TokenInfoRow>
{balance && <Balance balance={balance} />}
{selected && <StyledCheck size={20} />}
</TokenRow>
)
}
......
import { Currency } from '@uniswap/sdk-core'
import create from 'zustand'
import { devtools } from 'zustand/middleware'
interface TokenInputState {
inputCurrency: Currency | undefined
setInputCurrency: (currency: Currency | undefined) => void
clearInputCurrency: () => void
}
export const useTokenInput = create<TokenInputState>()(
devtools(
(set) => ({
inputCurrency: undefined,
setInputCurrency: (currency) => set(() => ({ inputCurrency: currency })),
clearInputCurrency: () => set(() => ({ inputCurrency: undefined })),
}),
{ name: 'useTokenInput' }
)
)
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