feat: add query param to disable the nft sections of the app (#6225)
* feat: add queryparam to disable the nft sections of the app * fix * include mini portfolio * add comments explaining nft disable atom usage and suggesting future work * add subtitle exception to landing page and correct the bool * update comment * comment syntax nits
This commit is contained in:
parent
a0f20c54d8
commit
048607080c
@ -6,6 +6,7 @@ import { useMGTMMicrositeEnabled } from 'featureFlags/flags/mgtm'
|
||||
import { chainIdToBackendName } from 'graphql/data/util'
|
||||
import { useIsNftPage } from 'hooks/useIsNftPage'
|
||||
import { useIsPoolsPage } from 'hooks/useIsPoolsPage'
|
||||
import { useAtomValue } from 'jotai/utils'
|
||||
import { Box } from 'nft/components/Box'
|
||||
import { Row } from 'nft/components/Flex'
|
||||
import { UniIcon } from 'nft/components/icons'
|
||||
@ -13,6 +14,7 @@ import { useProfilePageState } from 'nft/hooks'
|
||||
import { ProfilePageStateType } from 'nft/types'
|
||||
import { ReactNode } from 'react'
|
||||
import { NavLink, NavLinkProps, useLocation, useNavigate } from 'react-router-dom'
|
||||
import { shouldDisableNFTRoutesAtom } from 'state/application/atoms'
|
||||
import styled from 'styled-components/macro'
|
||||
|
||||
import { Bag } from './Bag'
|
||||
@ -60,6 +62,8 @@ export const PageTabs = () => {
|
||||
const isNftPage = useIsNftPage()
|
||||
const micrositeEnabled = useMGTMMicrositeEnabled()
|
||||
|
||||
const shouldDisableNFTRoutes = useAtomValue(shouldDisableNFTRoutesAtom)
|
||||
|
||||
return (
|
||||
<>
|
||||
<MenuItem href="/swap" isActive={pathname.startsWith('/swap')}>
|
||||
@ -68,9 +72,11 @@ export const PageTabs = () => {
|
||||
<MenuItem href={`/tokens/${chainName.toLowerCase()}`} isActive={pathname.startsWith('/tokens')}>
|
||||
<Trans>Tokens</Trans>
|
||||
</MenuItem>
|
||||
<MenuItem dataTestId="nft-nav" href="/nfts" isActive={isNftPage}>
|
||||
<Trans>NFTs</Trans>
|
||||
</MenuItem>
|
||||
{!shouldDisableNFTRoutes && (
|
||||
<MenuItem dataTestId="nft-nav" href="/nfts" isActive={isNftPage}>
|
||||
<Trans>NFTs</Trans>
|
||||
</MenuItem>
|
||||
)}
|
||||
<Box display={{ sm: 'flex', lg: 'none', xxl: 'flex' }} width="full">
|
||||
<MenuItem href="/pools" dataTestId="pool-nav-link" isActive={isPoolActive}>
|
||||
<Trans>Pools</Trans>
|
||||
|
@ -12,12 +12,14 @@ import { formatDelta } from 'components/Tokens/TokenDetails/PriceChart'
|
||||
import Tooltip from 'components/Tooltip'
|
||||
import { useGetConnection } from 'connection'
|
||||
import { usePortfolioBalancesQuery } from 'graphql/data/__generated__/types-and-hooks'
|
||||
import { useAtomValue } from 'jotai/utils'
|
||||
import { useProfilePageState, useSellAsset, useWalletCollections } from 'nft/hooks'
|
||||
import { useIsNftClaimAvailable } from 'nft/hooks/useIsNftClaimAvailable'
|
||||
import { ProfilePageStateType } from 'nft/types'
|
||||
import { useCallback, useState } from 'react'
|
||||
import { ArrowDownRight, ArrowUpRight, Copy, CreditCard, IconProps, Info, Power, Settings } from 'react-feather'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { shouldDisableNFTRoutesAtom } from 'state/application/atoms'
|
||||
import { useAppDispatch } from 'state/hooks'
|
||||
import { updateSelectedWallet } from 'state/user/reducer'
|
||||
import styled, { useTheme } from 'styled-components/macro'
|
||||
@ -166,6 +168,8 @@ export default function AuthenticatedHeader({ account, openSettings }: { account
|
||||
const clearCollectionFilters = useWalletCollections((state) => state.clearCollectionFilters)
|
||||
const isClaimAvailable = useIsNftClaimAvailable((state) => state.isClaimAvailable)
|
||||
|
||||
const shouldDisableNFTRoutes = useAtomValue(shouldDisableNFTRoutesAtom)
|
||||
|
||||
const unclaimedAmount: CurrencyAmount<Token> | undefined = useUserUnclaimedAmount(account)
|
||||
const isUnclaimed = useUserHasAvailableClaim(account)
|
||||
const getConnection = useGetConnection()
|
||||
@ -302,14 +306,16 @@ export default function AuthenticatedHeader({ account, openSettings }: { account
|
||||
</>
|
||||
)}
|
||||
</HeaderButton>
|
||||
<HeaderButton
|
||||
data-testid="nft-view-self-nfts"
|
||||
onClick={navigateToProfile}
|
||||
size={ButtonSize.medium}
|
||||
emphasis={ButtonEmphasis.medium}
|
||||
>
|
||||
<Trans>View and sell NFTs</Trans>
|
||||
</HeaderButton>
|
||||
{!shouldDisableNFTRoutes && (
|
||||
<HeaderButton
|
||||
data-testid="nft-view-self-nfts"
|
||||
onClick={navigateToProfile}
|
||||
size={ButtonSize.medium}
|
||||
emphasis={ButtonEmphasis.medium}
|
||||
>
|
||||
<Trans>View and sell NFTs</Trans>
|
||||
</HeaderButton>
|
||||
)}
|
||||
{Boolean(!fiatOnrampAvailable && fiatOnrampAvailabilityChecked) && (
|
||||
<FiatOnrampNotAvailableText marginTop="8px">
|
||||
<Trans>Not available in your region</Trans>
|
||||
|
@ -5,7 +5,9 @@ import Column from 'components/Column'
|
||||
import { AutoRow } from 'components/Row'
|
||||
import { useMiniPortfolioEnabled } from 'featureFlags/flags/miniPortfolio'
|
||||
import { useIsNftPage } from 'hooks/useIsNftPage'
|
||||
import { useAtomValue } from 'jotai/utils'
|
||||
import { useState } from 'react'
|
||||
import { shouldDisableNFTRoutesAtom } from 'state/application/atoms'
|
||||
import styled from 'styled-components/macro'
|
||||
import { ThemedText } from 'theme'
|
||||
|
||||
@ -75,27 +77,31 @@ const Pages: Array<Page> = [
|
||||
function MiniPortfolio({ account }: { account: string }) {
|
||||
const isNftPage = useIsNftPage()
|
||||
const [currentPage, setCurrentPage] = useState(isNftPage ? 1 : 0)
|
||||
const shouldDisableNFTRoutes = useAtomValue(shouldDisableNFTRoutesAtom)
|
||||
|
||||
const Page = Pages[currentPage].component
|
||||
return (
|
||||
<Wrapper>
|
||||
<Nav>
|
||||
{Pages.map(({ title }, index) => (
|
||||
<TraceEvent
|
||||
events={[BrowserEvent.onClick]}
|
||||
name={SharedEventName.NAVBAR_CLICKED}
|
||||
element={Pages[index].loggingElementName}
|
||||
key={index}
|
||||
>
|
||||
<NavItem
|
||||
onClick={() => setCurrentPage(index)}
|
||||
active={currentPage === index}
|
||||
key={`Mini Portfolio page ${index}`}
|
||||
{Pages.map(({ title, loggingElementName }, index) => {
|
||||
if (shouldDisableNFTRoutes && loggingElementName.includes('nft')) return null
|
||||
return (
|
||||
<TraceEvent
|
||||
events={[BrowserEvent.onClick]}
|
||||
name={SharedEventName.NAVBAR_CLICKED}
|
||||
element={loggingElementName}
|
||||
key={index}
|
||||
>
|
||||
{title}
|
||||
</NavItem>
|
||||
</TraceEvent>
|
||||
))}
|
||||
<NavItem
|
||||
onClick={() => setCurrentPage(index)}
|
||||
active={currentPage === index}
|
||||
key={`Mini Portfolio page ${index}`}
|
||||
>
|
||||
{title}
|
||||
</NavItem>
|
||||
</TraceEvent>
|
||||
)
|
||||
})}
|
||||
</Nav>
|
||||
<PageWrapper>
|
||||
<Page account={account} />
|
||||
|
@ -6,9 +6,11 @@ import TopLevelModals from 'components/TopLevelModals'
|
||||
import { useFeatureFlagsIsLoaded } from 'featureFlags'
|
||||
import { useMGTMMicrositeEnabled } from 'featureFlags/flags/mgtm'
|
||||
import ApeModeQueryParamReader from 'hooks/useApeModeQueryParamReader'
|
||||
import { useAtom } from 'jotai'
|
||||
import { useBag } from 'nft/hooks/useBag'
|
||||
import { lazy, Suspense, useEffect, useMemo, useState } from 'react'
|
||||
import { Navigate, Route, Routes, useLocation } from 'react-router-dom'
|
||||
import { Navigate, Route, Routes, useLocation, useSearchParams } from 'react-router-dom'
|
||||
import { shouldDisableNFTRoutesAtom } from 'state/application/atoms'
|
||||
import { StatsigProvider, StatsigUser } from 'statsig-react'
|
||||
import styled from 'styled-components/macro'
|
||||
import { SpinnerSVG } from 'theme/components'
|
||||
@ -132,6 +134,7 @@ const LazyLoadSpinner = () => (
|
||||
|
||||
export default function App() {
|
||||
const isLoaded = useFeatureFlagsIsLoaded()
|
||||
const [shouldDisableNFTRoutes, setShouldDisableNFTRoutes] = useAtom(shouldDisableNFTRoutesAtom)
|
||||
|
||||
const { pathname } = useLocation()
|
||||
const currentPage = getCurrentPageFromLocation(pathname)
|
||||
@ -146,6 +149,15 @@ export default function App() {
|
||||
setScrolledState(false)
|
||||
}, [pathname])
|
||||
|
||||
const [searchParams] = useSearchParams()
|
||||
useEffect(() => {
|
||||
if (searchParams.get('disableNFTs') === 'true') {
|
||||
setShouldDisableNFTRoutes(true)
|
||||
} else if (searchParams.get('disableNFTs') === 'false') {
|
||||
setShouldDisableNFTRoutes(false)
|
||||
}
|
||||
}, [searchParams, setShouldDisableNFTRoutes])
|
||||
|
||||
useEffect(() => {
|
||||
// User properties *must* be set before sending corresponding event properties,
|
||||
// so that the event contains the correct and up-to-date user properties.
|
||||
@ -271,46 +283,54 @@ export default function App() {
|
||||
<Route path="migrate/v2" element={<MigrateV2 />} />
|
||||
<Route path="migrate/v2/:address" element={<MigrateV2Pair />} />
|
||||
|
||||
<Route
|
||||
path="/nfts"
|
||||
element={
|
||||
<Suspense fallback={null}>
|
||||
<NftExplore />
|
||||
</Suspense>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/nfts/asset/:contractAddress/:tokenId"
|
||||
element={
|
||||
<Suspense fallback={null}>
|
||||
<Asset />
|
||||
</Suspense>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/nfts/profile"
|
||||
element={
|
||||
<Suspense fallback={null}>
|
||||
<Profile />
|
||||
</Suspense>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/nfts/collection/:contractAddress"
|
||||
element={
|
||||
<Suspense fallback={null}>
|
||||
<Collection />
|
||||
</Suspense>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/nfts/collection/:contractAddress/activity"
|
||||
element={
|
||||
<Suspense fallback={null}>
|
||||
<Collection />
|
||||
</Suspense>
|
||||
}
|
||||
/>
|
||||
{!shouldDisableNFTRoutes && (
|
||||
<>
|
||||
<Route
|
||||
path="/nfts"
|
||||
element={
|
||||
<Suspense fallback={null}>
|
||||
<NftExplore />
|
||||
</Suspense>
|
||||
}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/nfts/asset/:contractAddress/:tokenId"
|
||||
element={
|
||||
<Suspense fallback={null}>
|
||||
<Asset />
|
||||
</Suspense>
|
||||
}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/nfts/profile"
|
||||
element={
|
||||
<Suspense fallback={null}>
|
||||
<Profile />
|
||||
</Suspense>
|
||||
}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/nfts/collection/:contractAddress"
|
||||
element={
|
||||
<Suspense fallback={null}>
|
||||
<Collection />
|
||||
</Suspense>
|
||||
}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/nfts/collection/:contractAddress/activity"
|
||||
element={
|
||||
<Suspense fallback={null}>
|
||||
<Collection />
|
||||
</Suspense>
|
||||
}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
<Route path="*" element={<Navigate to="/not-found" replace />} />
|
||||
<Route path="/not-found" element={<NotFound />} />
|
||||
|
@ -7,12 +7,14 @@ import { MAIN_CARDS, MORE_CARDS } from 'components/About/constants'
|
||||
import ProtocolBanner from 'components/About/ProtocolBanner'
|
||||
import { BaseButton } from 'components/Button'
|
||||
import { useSwapWidgetEnabled } from 'featureFlags/flags/swapWidget'
|
||||
import { useAtomValue } from 'jotai/utils'
|
||||
import Swap from 'pages/Swap'
|
||||
import { parse } from 'qs'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { ArrowDownCircle } from 'react-feather'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import { Link as NativeLink } from 'react-router-dom'
|
||||
import { shouldDisableNFTRoutesAtom } from 'state/application/atoms'
|
||||
import { useAppSelector } from 'state/hooks'
|
||||
import styled, { css } from 'styled-components/macro'
|
||||
import { BREAKPOINTS } from 'theme'
|
||||
@ -316,6 +318,8 @@ export default function Landing() {
|
||||
}
|
||||
}, [navigate, selectedWallet, queryParams.intro])
|
||||
|
||||
const shouldDisableNFTRoutes = useAtomValue(shouldDisableNFTRoutesAtom)
|
||||
|
||||
return (
|
||||
<Trace page={InterfacePageName.LANDING_PAGE} shouldLogImpression>
|
||||
{showContent && (
|
||||
@ -342,9 +346,21 @@ export default function Landing() {
|
||||
<Glow />
|
||||
</GlowContainer>
|
||||
<ContentContainer isDarkMode={isDarkMode}>
|
||||
<TitleText isDarkMode={isDarkMode}>Trade crypto & NFTs with confidence</TitleText>
|
||||
<TitleText isDarkMode={isDarkMode}>
|
||||
{shouldDisableNFTRoutes ? (
|
||||
<Trans>Trade crypto with confidence</Trans>
|
||||
) : (
|
||||
<Trans>Trade crypto and NFTs with confidence</Trans>
|
||||
)}
|
||||
</TitleText>
|
||||
<SubTextContainer>
|
||||
<SubText>Buy, sell, and explore tokens and NFTs</SubText>
|
||||
<SubText>
|
||||
{shouldDisableNFTRoutes ? (
|
||||
<Trans>Buy, sell, and explore tokens</Trans>
|
||||
) : (
|
||||
<Trans>Buy, sell, and explore tokens and NFTs</Trans>
|
||||
)}
|
||||
</SubText>
|
||||
</SubTextContainer>
|
||||
<ActionsContainer>
|
||||
<TraceEvent
|
||||
|
14
src/state/application/atoms.ts
Normal file
14
src/state/application/atoms.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { atomWithStorage, createJSONStorage } from 'jotai/utils'
|
||||
|
||||
/*
|
||||
Note:
|
||||
We should consider a generic sessionStorage abstraction if this pattern becomes common. (i.e., Future promo dismissals like the tax service discounts or Fiat Onramp launch notification may use this.)
|
||||
This would be something similar to the current feature flag implementation, but utilizing session instead
|
||||
|
||||
Motivation:
|
||||
some dapp browsers need to be able to disable the NFT portion of the app in order to pass Apple's app store review
|
||||
this atom persists the inclusion of the `disableNFTs=boolean` query parameter via the webview's session storage
|
||||
*/
|
||||
const storage = createJSONStorage(() => sessionStorage)
|
||||
|
||||
export const shouldDisableNFTRoutesAtom = atomWithStorage('shouldDisableNFTRoutes', false, storage)
|
Loading…
Reference in New Issue
Block a user