feat: [info] add new tdp nav (#7531)
* feat: [info] add new tdp nav * tidy up code * pr review * nit remove unused component style * pr review * lol extraneous extra
This commit is contained in:
parent
712f82cb1a
commit
876d3a1cc3
@ -1,6 +1,7 @@
|
||||
import { Trans } from '@lingui/macro'
|
||||
import styled from 'styled-components'
|
||||
import { CopyContractAddress, ThemedText } from 'theme/components'
|
||||
import { shortenAddress } from 'utils/addresses'
|
||||
|
||||
const ContractAddressSection = styled.div`
|
||||
display: flex;
|
||||
@ -29,7 +30,7 @@ export default function AddressSection({ address }: { address: string }) {
|
||||
<Trans>Contract address</Trans>
|
||||
</ThemedText.SubHeaderSmall>
|
||||
<ContractAddress>
|
||||
<CopyContractAddress address={address} />
|
||||
<CopyContractAddress address={address} truncatedAddress={shortenAddress(address, 2, 3)} />
|
||||
</ContractAddress>
|
||||
</ContractAddressSection>
|
||||
)
|
||||
|
@ -1,17 +1,31 @@
|
||||
import { Link } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
import styled, { css } from 'styled-components'
|
||||
|
||||
export const BreadcrumbNav = styled.div<{ isInfoTDPEnabled?: boolean }>`
|
||||
display: flex;
|
||||
color: ${({ theme }) => theme.neutral1};
|
||||
${({ isInfoTDPEnabled }) =>
|
||||
isInfoTDPEnabled
|
||||
? css`
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
`
|
||||
: css`
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
`}
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
margin-bottom: 16px;
|
||||
width: fit-content;
|
||||
`
|
||||
|
||||
export const BreadcrumbNavLink = styled(Link)`
|
||||
display: flex;
|
||||
color: ${({ theme }) => theme.neutral2};
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
text-decoration: none;
|
||||
margin-bottom: 16px;
|
||||
color: ${({ theme }) => theme.neutral2};
|
||||
transition-duration: ${({ theme }) => theme.transition.duration.fast};
|
||||
width: fit-content;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
color: ${({ theme }) => theme.neutral3};
|
||||
|
@ -1,6 +1,8 @@
|
||||
import { Trans } from '@lingui/macro'
|
||||
import { SwapSkeleton } from 'components/swap/SwapSkeleton'
|
||||
import { useInfoExplorePageEnabled } from 'featureFlags/flags/infoExplore'
|
||||
import { ArrowLeft } from 'react-feather'
|
||||
import { useInfoTDPEnabled } from 'featureFlags/flags/infoTDP'
|
||||
import { ArrowLeft, ChevronRight } from 'react-feather'
|
||||
import { useParams } from 'react-router-dom'
|
||||
import styled, { useTheme } from 'styled-components'
|
||||
import { ThemedText } from 'theme/components'
|
||||
@ -8,7 +10,7 @@ import { textFadeIn } from 'theme/styles'
|
||||
|
||||
import { LoadingBubble } from '../loading'
|
||||
import { AboutContainer, AboutHeader } from './About'
|
||||
import { BreadcrumbNavLink } from './BreadcrumbNavLink'
|
||||
import { BreadcrumbNav, BreadcrumbNavLink } from './BreadcrumbNavLink'
|
||||
import { StatPair, StatsWrapper, StatWrapper } from './StatsSection'
|
||||
|
||||
const SWAP_COMPONENT_WIDTH = 360
|
||||
@ -92,6 +94,9 @@ const SquaredBubble = styled(DetailBubble)`
|
||||
height: 32px;
|
||||
border-radius: 8px;
|
||||
`
|
||||
const NavBubble = styled(DetailBubble)`
|
||||
width: 169px;
|
||||
`
|
||||
const TokenLogoBubble = styled(DetailBubble)`
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
@ -222,13 +227,26 @@ function LoadingStats() {
|
||||
export default function TokenDetailsSkeleton() {
|
||||
const { chainName } = useParams<{ chainName?: string }>()
|
||||
const isInfoExplorePageEnabled = useInfoExplorePageEnabled()
|
||||
const isInfoTDPEnabled = useInfoTDPEnabled()
|
||||
|
||||
return (
|
||||
<LeftPanel>
|
||||
<BreadcrumbNavLink
|
||||
to={(isInfoExplorePageEnabled ? '/explore' : '') + (chainName ? `/tokens/${chainName}` : `/tokens`)}
|
||||
>
|
||||
<ArrowLeft size={14} /> Tokens
|
||||
</BreadcrumbNavLink>
|
||||
{isInfoTDPEnabled ? (
|
||||
<BreadcrumbNav isInfoTDPEnabled>
|
||||
<BreadcrumbNavLink to={`${isInfoExplorePageEnabled ? '/explore' : ''}/tokens/${chainName}`}>
|
||||
<Trans>Explore</Trans> <ChevronRight size={14} /> <Trans>Tokens</Trans> <ChevronRight size={14} />
|
||||
</BreadcrumbNavLink>{' '}
|
||||
<NavBubble />
|
||||
</BreadcrumbNav>
|
||||
) : (
|
||||
<BreadcrumbNav>
|
||||
<BreadcrumbNavLink
|
||||
to={(isInfoExplorePageEnabled ? '/explore' : '') + (chainName ? `/tokens/${chainName}` : `/tokens`)}
|
||||
>
|
||||
<ArrowLeft size={14} /> Tokens
|
||||
</BreadcrumbNavLink>
|
||||
</BreadcrumbNav>
|
||||
)}
|
||||
<TokenInfoContainer>
|
||||
<TokenNameCell>
|
||||
<TokenLogoBubble />
|
||||
|
@ -6,7 +6,7 @@ import { PortfolioLogo } from 'components/AccountDrawer/MiniPortfolio/PortfolioL
|
||||
import { AboutSection } from 'components/Tokens/TokenDetails/About'
|
||||
import AddressSection from 'components/Tokens/TokenDetails/AddressSection'
|
||||
import BalanceSummary from 'components/Tokens/TokenDetails/BalanceSummary'
|
||||
import { BreadcrumbNavLink } from 'components/Tokens/TokenDetails/BreadcrumbNavLink'
|
||||
import { BreadcrumbNav, BreadcrumbNavLink } from 'components/Tokens/TokenDetails/BreadcrumbNavLink'
|
||||
import ChartSection from 'components/Tokens/TokenDetails/ChartSection'
|
||||
import MobileBalanceSummaryFooter from 'components/Tokens/TokenDetails/MobileBalanceSummaryFooter'
|
||||
import ShareButton from 'components/Tokens/TokenDetails/ShareButton'
|
||||
@ -32,12 +32,13 @@ import { useOnGlobalChainSwitch } from 'hooks/useGlobalChainSwitch'
|
||||
import { UNKNOWN_TOKEN_SYMBOL, useTokenFromActiveNetwork } from 'lib/hooks/useCurrency'
|
||||
import { Swap } from 'pages/Swap'
|
||||
import { useCallback, useMemo, useState, useTransition } from 'react'
|
||||
import { ArrowLeft } from 'react-feather'
|
||||
import { ArrowLeft, ChevronRight } from 'react-feather'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { Field } from 'state/swap/actions'
|
||||
import { SwapState } from 'state/swap/reducer'
|
||||
import styled from 'styled-components'
|
||||
import { isAddress } from 'utils'
|
||||
import { CopyContractAddress } from 'theme/components'
|
||||
import { isAddress, shortenAddress } from 'utils'
|
||||
import { addressesAreEquivalent } from 'utils/addressesAreEquivalent'
|
||||
|
||||
import { OnChangeTimePeriod } from './ChartSection'
|
||||
@ -130,7 +131,6 @@ export default function TokenDetails({
|
||||
}, {} as { [key: string]: string | undefined }) ?? {},
|
||||
[tokenQueryData]
|
||||
)
|
||||
const isInfoTDPEnabled = useInfoTDPEnabled()
|
||||
|
||||
const { token: detailedToken, didFetchFromChain } = useRelevantToken(address, pageChainId, tokenQueryData)
|
||||
|
||||
@ -139,6 +139,7 @@ export default function TokenDetails({
|
||||
const navigate = useNavigate()
|
||||
|
||||
const isInfoExplorePageEnabled = useInfoExplorePageEnabled()
|
||||
const isInfoTDPEnabled = useInfoTDPEnabled()
|
||||
|
||||
// Wrapping navigate in a transition prevents Suspense from unnecessarily showing fallbacks again.
|
||||
const [isPending, startTokenTransition] = useTransition()
|
||||
@ -210,6 +211,7 @@ export default function TokenDetails({
|
||||
if (detailedToken === undefined || !address) {
|
||||
return <InvalidTokenDetails pageChainId={pageChainId} isInvalidAddress={!address} />
|
||||
}
|
||||
const tokenSymbolName = detailedToken && (detailedToken.symbol ?? <Trans>Symbol not found</Trans>)
|
||||
return (
|
||||
<Trace
|
||||
page={InterfacePageName.TOKEN_DETAILS_PAGE}
|
||||
@ -219,15 +221,37 @@ export default function TokenDetails({
|
||||
<TokenDetailsLayout>
|
||||
{detailedToken && !isPending ? (
|
||||
<LeftPanel>
|
||||
<BreadcrumbNavLink to={`${isInfoExplorePageEnabled ? '/explore' : ''}/tokens/${chain.toLowerCase()}`}>
|
||||
<ArrowLeft data-testid="token-details-return-button" size={14} /> Tokens
|
||||
</BreadcrumbNavLink>
|
||||
{isInfoTDPEnabled ? (
|
||||
<BreadcrumbNav isInfoTDPEnabled>
|
||||
<BreadcrumbNavLink to={`${isInfoExplorePageEnabled ? '/explore' : ''}/tokens/${chain.toLowerCase()}`}>
|
||||
<Trans>Explore</Trans> <ChevronRight size={14} /> <Trans>Tokens</Trans> <ChevronRight size={14} />
|
||||
</BreadcrumbNavLink>{' '}
|
||||
{tokenSymbolName}{' '}
|
||||
{!detailedToken.isNative && (
|
||||
<>
|
||||
(
|
||||
<CopyContractAddress
|
||||
address={address}
|
||||
showTruncatedOnly
|
||||
truncatedAddress={shortenAddress(address)}
|
||||
/>
|
||||
)
|
||||
</>
|
||||
)}
|
||||
</BreadcrumbNav>
|
||||
) : (
|
||||
<BreadcrumbNav>
|
||||
<BreadcrumbNavLink to={`${isInfoExplorePageEnabled ? '/explore' : ''}/tokens/${chain.toLowerCase()}`}>
|
||||
<ArrowLeft data-testid="token-details-return-button" size={14} /> Tokens
|
||||
</BreadcrumbNavLink>
|
||||
</BreadcrumbNav>
|
||||
)}
|
||||
<TokenInfoContainer data-testid="token-info-container">
|
||||
<TokenNameCell>
|
||||
<PortfolioLogo currencies={[detailedToken]} chainId={detailedToken.chainId} size="32px" />
|
||||
<TokenTitle>
|
||||
{detailedToken.name ?? <Trans>Name not found</Trans>}
|
||||
<TokenSymbol>{detailedToken.symbol ?? <Trans>Symbol not found</Trans>}</TokenSymbol>
|
||||
<TokenSymbol>{tokenSymbolName}</TokenSymbol>
|
||||
</TokenTitle>
|
||||
</TokenNameCell>
|
||||
<TokenActions>
|
||||
|
@ -243,13 +243,14 @@ export function CopyLinkIcon({ toCopy }: { toCopy: string }) {
|
||||
)
|
||||
}
|
||||
|
||||
const FullAddress = styled.span`
|
||||
const FullAddress = styled.span<{ showTruncated?: boolean }>`
|
||||
${({ showTruncated }) => showTruncated && 'display: none;'}
|
||||
@media only screen and (max-width: ${MOBILE_MEDIA_BREAKPOINT}) {
|
||||
display: none;
|
||||
}
|
||||
`
|
||||
const TruncatedAddress = styled.span`
|
||||
display: none;
|
||||
const TruncatedAddress = styled.span<{ showTruncated?: boolean }>`
|
||||
display: ${({ showTruncated }) => (showTruncated ? 'flex' : 'none')};
|
||||
@media only screen and (max-width: ${MOBILE_MEDIA_BREAKPOINT}) {
|
||||
display: flex;
|
||||
}
|
||||
@ -273,7 +274,15 @@ const CopyContractAddressWrapper = styled.div`
|
||||
display: flex;
|
||||
`
|
||||
|
||||
export function CopyContractAddress({ address }: { address: string }) {
|
||||
export function CopyContractAddress({
|
||||
address,
|
||||
showTruncatedOnly,
|
||||
truncatedAddress,
|
||||
}: {
|
||||
address: string
|
||||
showTruncatedOnly?: boolean
|
||||
truncatedAddress?: string
|
||||
}) {
|
||||
const [isCopied, setCopied] = useCopyClipboard()
|
||||
const [tooltipX, setTooltipX] = useState<number | undefined>()
|
||||
const copy = useCallback(
|
||||
@ -284,12 +293,11 @@ export function CopyContractAddress({ address }: { address: string }) {
|
||||
[address, setCopied]
|
||||
)
|
||||
|
||||
const truncated = `${address.slice(0, 4)}...${address.slice(-3)}`
|
||||
return (
|
||||
<CopyContractAddressWrapper onClick={copy}>
|
||||
<CopyAddressRow isClicked={isCopied}>
|
||||
<FullAddress>{address}</FullAddress>
|
||||
<TruncatedAddress>{truncated}</TruncatedAddress>
|
||||
<FullAddress showTruncated={showTruncatedOnly}>{address}</FullAddress>
|
||||
<TruncatedAddress showTruncated={showTruncatedOnly}>{truncatedAddress}</TruncatedAddress>
|
||||
<Copy size={14} />
|
||||
</CopyAddressRow>
|
||||
{isCopied && <Tooltip isCopyContractTooltip tooltipX={tooltipX} />}
|
||||
|
Loading…
Reference in New Issue
Block a user