feat: add token explore promo banner (#4481)
* initial design * progress * add background image * add logic * update * delete unneed state * more * redux * redux * more redux * rebase main * rm unused state * rm unused export * relative link
This commit is contained in:
parent
c9e2f86e57
commit
6f3579acf1
BIN
src/assets/images/tokensPromoDark.png
Normal file
BIN
src/assets/images/tokensPromoDark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 58 KiB |
BIN
src/assets/images/tokensPromoLight.png
Normal file
BIN
src/assets/images/tokensPromoLight.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
75
src/components/Tokens/TokensBanner.tsx
Normal file
75
src/components/Tokens/TokensBanner.tsx
Normal file
@ -0,0 +1,75 @@
|
||||
import { X } from 'react-feather'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { useShowTokensPromoBanner } from 'state/user/hooks'
|
||||
import styled, { useTheme } from 'styled-components/macro'
|
||||
import { opacify } from 'theme/utils'
|
||||
|
||||
import tokensPromoDark from '../../assets/images/tokensPromoDark.png'
|
||||
import tokensPromoLight from '../../assets/images/tokensPromoLight.png'
|
||||
|
||||
const PopupContainer = styled.div<{ show: boolean }>`
|
||||
position: absolute;
|
||||
display: ${({ show }) => (show ? 'flex' : 'none')};
|
||||
flex-direction: column;
|
||||
padding: 12px 16px 12px 20px;
|
||||
gap: 8px;
|
||||
bottom: 48px;
|
||||
right: 16px;
|
||||
width: 320px;
|
||||
height: 88px;
|
||||
z-index: 5;
|
||||
background-color: ${({ theme }) => (theme.darkMode ? theme.backgroundScrim : opacify(60, '#FDF0F8'))};
|
||||
color: ${({ theme }) => theme.textPrimary};
|
||||
border: 1px solid ${({ theme }) => theme.backgroundOutline};
|
||||
border-radius: 12px;
|
||||
box-shadow: ${({ theme }) => theme.deepShadow};
|
||||
|
||||
background-image: url(${({ theme }) => (theme.darkMode ? `${tokensPromoDark}` : `${tokensPromoLight}`)});
|
||||
background-size: cover;
|
||||
background-blend-mode: overlay;
|
||||
|
||||
transition: ${({
|
||||
theme: {
|
||||
transition: { duration, timing },
|
||||
},
|
||||
}) => `${duration.slow}ms opacity ${timing.in}`};
|
||||
`
|
||||
const Header = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
`
|
||||
const HeaderText = styled(Link)`
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
text-decoration: none;
|
||||
`
|
||||
const Description = styled.span`
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
width: 75%;
|
||||
`
|
||||
|
||||
export default function TokensBanner() {
|
||||
const theme = useTheme()
|
||||
const [showTokensPromoBanner, setShowTokensPromoBanner] = useShowTokensPromoBanner()
|
||||
|
||||
const closeBanner = () => {
|
||||
setShowTokensPromoBanner(false)
|
||||
}
|
||||
|
||||
return (
|
||||
<PopupContainer show={showTokensPromoBanner}>
|
||||
<Header>
|
||||
<HeaderText to={'/#/tokens'} onClick={closeBanner}>
|
||||
Explore Top Tokens
|
||||
</HeaderText>
|
||||
<X size={20} color={theme.textSecondary} onClick={closeBanner} style={{ cursor: 'pointer' }} />
|
||||
</Header>
|
||||
|
||||
<Description onClick={closeBanner}>Check out the new explore tab to discover and learn more</Description>
|
||||
</PopupContainer>
|
||||
)
|
||||
}
|
@ -10,8 +10,10 @@ import { FlyoutAlignment, NewMenu } from 'components/Menu'
|
||||
import PositionList from 'components/PositionList'
|
||||
import { RowBetween, RowFixed } from 'components/Row'
|
||||
import { SwitchLocaleLink } from 'components/SwitchLocaleLink'
|
||||
import TokensBanner from 'components/Tokens/TokensBanner'
|
||||
import { isSupportedChain } from 'constants/chains'
|
||||
import { NavBarVariant, useNavBarFlag } from 'featureFlags/flags/navBar'
|
||||
import { TokensVariant, useTokensFlag } from 'featureFlags/flags/tokens'
|
||||
import { useV3Positions } from 'hooks/useV3Positions'
|
||||
import { AlertTriangle, BookOpen, ChevronDown, ChevronsRight, Inbox, Layers, PlusCircle } from 'react-feather'
|
||||
import { Link } from 'react-router-dom'
|
||||
@ -164,8 +166,10 @@ function WrongNetworkCard() {
|
||||
const navBarFlag = useNavBarFlag()
|
||||
const navBarFlagEnabled = navBarFlag === NavBarVariant.Enabled
|
||||
const theme = useTheme()
|
||||
const tokensFlag = useTokensFlag()
|
||||
return (
|
||||
<>
|
||||
{tokensFlag === TokensVariant.Enabled && <TokensBanner />}
|
||||
<PageWrapper navBarFlag={navBarFlagEnabled}>
|
||||
<AutoColumn gap="lg" justify="center">
|
||||
<AutoColumn gap="lg" style={{ width: '100%' }}>
|
||||
|
@ -17,11 +17,13 @@ import { NetworkAlert } from 'components/NetworkAlert/NetworkAlert'
|
||||
import PriceImpactWarning from 'components/swap/PriceImpactWarning'
|
||||
import SwapDetailsDropdown from 'components/swap/SwapDetailsDropdown'
|
||||
import UnsupportedCurrencyFooter from 'components/swap/UnsupportedCurrencyFooter'
|
||||
import TokensBanner from 'components/Tokens/TokensBanner'
|
||||
import TokenSafetyModal from 'components/TokenSafety/TokenSafetyModal'
|
||||
import { MouseoverTooltip } from 'components/Tooltip'
|
||||
import { isSupportedChain } from 'constants/chains'
|
||||
import { NavBarVariant, useNavBarFlag } from 'featureFlags/flags/navBar'
|
||||
import { RedesignVariant, useRedesignFlag } from 'featureFlags/flags/redesign'
|
||||
import { TokensVariant, useTokensFlag } from 'featureFlags/flags/tokens'
|
||||
import { useSwapCallback } from 'hooks/useSwapCallback'
|
||||
import useTransactionDeadline from 'hooks/useTransactionDeadline'
|
||||
import JSBI from 'jsbi'
|
||||
@ -154,6 +156,7 @@ export default function Swap() {
|
||||
const navBarFlagEnabled = navBarFlag === NavBarVariant.Enabled
|
||||
const redesignFlag = useRedesignFlag()
|
||||
const redesignFlagEnabled = redesignFlag === RedesignVariant.Enabled
|
||||
const tokensFlag = useTokensFlag()
|
||||
const { account, chainId } = useWeb3React()
|
||||
const loadedUrlParams = useDefaultsFromURLSearch()
|
||||
const [newSwapQuoteNeedsLogging, setNewSwapQuoteNeedsLogging] = useState(true)
|
||||
@ -505,6 +508,7 @@ export default function Swap() {
|
||||
return (
|
||||
<Trace page={PageName.SWAP_PAGE} shouldLogImpression>
|
||||
<>
|
||||
{tokensFlag === TokensVariant.Enabled && <TokensBanner />}
|
||||
{redesignFlagEnabled ? (
|
||||
<TokenSafetyModal
|
||||
isOpen={importTokensNotInDefault.length > 0 && !dismissTokenWarning}
|
||||
|
@ -19,6 +19,7 @@ import {
|
||||
removeSerializedToken,
|
||||
updateHideClosedPositions,
|
||||
updateShowSurveyPopup,
|
||||
updateShowTokensPromoBanner,
|
||||
updateUserClientSideRouter,
|
||||
updateUserDarkMode,
|
||||
updateUserDeadline,
|
||||
@ -116,6 +117,18 @@ export function useShowSurveyPopup(): [boolean | undefined, (showPopup: boolean)
|
||||
return [showSurveyPopup, toggleShowSurveyPopup]
|
||||
}
|
||||
|
||||
export function useShowTokensPromoBanner(): [boolean, (showTokensBanner: boolean) => void] {
|
||||
const dispatch = useAppDispatch()
|
||||
const showTokensPromoBanner = useAppSelector((state) => state.user.showTokensPromoBanner)
|
||||
const toggleShowTokensPromoBanner = useCallback(
|
||||
(showTokensBanner: boolean) => {
|
||||
dispatch(updateShowTokensPromoBanner({ showTokensPromoBanner: showTokensBanner }))
|
||||
},
|
||||
[dispatch]
|
||||
)
|
||||
return [showTokensPromoBanner, toggleShowTokensPromoBanner]
|
||||
}
|
||||
|
||||
export function useClientSideRouter(): [boolean, (userClientSideRouter: boolean) => void] {
|
||||
const dispatch = useAppDispatch()
|
||||
|
||||
|
@ -53,6 +53,8 @@ export interface UserState {
|
||||
showSurveyPopup: boolean | undefined
|
||||
|
||||
showDonationLink: boolean
|
||||
|
||||
showTokensPromoBanner: boolean // show tokens promo banner for token explore
|
||||
}
|
||||
|
||||
function pairKey(token0Address: string, token1Address: string) {
|
||||
@ -76,6 +78,7 @@ export const initialState: UserState = {
|
||||
URLWarningVisible: true,
|
||||
showSurveyPopup: undefined,
|
||||
showDonationLink: true,
|
||||
showTokensPromoBanner: true,
|
||||
}
|
||||
|
||||
const userSlice = createSlice({
|
||||
@ -121,6 +124,9 @@ const userSlice = createSlice({
|
||||
updateShowDonationLink(state, action) {
|
||||
state.showDonationLink = action.payload.showDonationLink
|
||||
},
|
||||
updateShowTokensPromoBanner(state, action) {
|
||||
state.showTokensPromoBanner = action.payload.showTokensPromoBanner
|
||||
},
|
||||
addSerializedToken(state, { payload: { serializedToken } }) {
|
||||
if (!state.tokens) {
|
||||
state.tokens = {}
|
||||
@ -210,5 +216,6 @@ export const {
|
||||
updateUserExpertMode,
|
||||
updateUserLocale,
|
||||
updateUserSlippageTolerance,
|
||||
updateShowTokensPromoBanner,
|
||||
} = userSlice.actions
|
||||
export default userSlice.reducer
|
||||
|
Loading…
Reference in New Issue
Block a user