Commit bf31ca4f authored by cartcrom's avatar cartcrom Committed by GitHub

feat: updated banner (#6355)

* feat: updated banner

* fix: linted

* feat: add download link to overflow menu

* feat: hover animation

* fix: update landing screen hide logic

* feat: added descriptor comment for stopPropogation

* fix: translations & responsiveness of button text

* fix: icon sizing / padding + word casing

* fix: Learn more casing
parent ed8afbd8
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -38,10 +38,17 @@ const MICROSITE_LINK = 'https://wallet.uniswap.org/' ...@@ -38,10 +38,17 @@ const MICROSITE_LINK = 'https://wallet.uniswap.org/'
const openAppStore = () => { const openAppStore = () => {
window.open(APP_STORE_LINK, /* target = */ 'uniswap_wallet_appstore') window.open(APP_STORE_LINK, /* target = */ 'uniswap_wallet_appstore')
} }
const openWalletMicrosite = () => { export const openWalletMicrosite = () => {
sendAnalyticsEvent(InterfaceEventName.UNISWAP_WALLET_MICROSITE_OPENED) sendAnalyticsEvent(InterfaceEventName.UNISWAP_WALLET_MICROSITE_OPENED)
window.open(MICROSITE_LINK, /* target = */ 'uniswap_wallet_microsite') window.open(MICROSITE_LINK, /* target = */ 'uniswap_wallet_microsite')
} }
export function openDownloadApp(element: InterfaceElementName) {
sendAnalyticsEvent(SharedEventName.ELEMENT_CLICKED, { element })
if (isIOS) openAppStore()
else openWalletMicrosite()
}
// Launches App Store if on an iOS device, else navigates to Uniswap Wallet microsite // Launches App Store if on an iOS device, else navigates to Uniswap Wallet microsite
export function DownloadButton({ export function DownloadButton({
onClick, onClick,
...@@ -55,9 +62,7 @@ export function DownloadButton({ ...@@ -55,9 +62,7 @@ export function DownloadButton({
const onButtonClick = useCallback(() => { const onButtonClick = useCallback(() => {
// handles any actions required by the parent, i.e. cancelling wallet connection attempt or dismissing an ad // handles any actions required by the parent, i.e. cancelling wallet connection attempt or dismissing an ad
onClick?.() onClick?.()
sendAnalyticsEvent(SharedEventName.ELEMENT_CLICKED, { element }) openDownloadApp(element)
if (isIOS) openAppStore()
else openWalletMicrosite()
}, [element, onClick]) }, [element, onClick])
return ( return (
...@@ -66,7 +71,3 @@ export function DownloadButton({ ...@@ -66,7 +71,3 @@ export function DownloadButton({
</BaseButton> </BaseButton>
) )
} }
export function LearnMoreButton() {
return <BaseButton onClick={openWalletMicrosite}>Learn More</BaseButton>
}
import { Trans } from '@lingui/macro' import { Trans } from '@lingui/macro'
import { InterfaceElementName } from '@uniswap/analytics-events' import { InterfaceElementName } from '@uniswap/analytics-events'
import { useAccountDrawer } from 'components/AccountDrawer' import { openDownloadApp, openWalletMicrosite } from 'components/AccountDrawer/DownloadButton'
import { DownloadButton, LearnMoreButton } from 'components/AccountDrawer/DownloadButton' import { BaseButton } from 'components/Button'
import { AutoColumn } from 'components/Column' import { AutoColumn } from 'components/Column'
import Row, { RowBetween } from 'components/Row' import { OpacityHoverState } from 'components/Common'
import Row from 'components/Row'
import { useMgtmEnabled } from 'featureFlags/flags/mgtm' import { useMgtmEnabled } from 'featureFlags/flags/mgtm'
import { useScreenSize } from 'hooks/useScreenSize'
import { X } from 'react-feather' import { X } from 'react-feather'
import { useLocation } from 'react-router-dom'
import { useHideUniswapWalletBanner } from 'state/user/hooks' import { useHideUniswapWalletBanner } from 'state/user/hooks'
import styled, { useTheme } from 'styled-components/macro' import styled from 'styled-components/macro'
import { ThemedText } from 'theme' import { ThemedText } from 'theme'
import { Z_INDEX } from 'theme/zIndex' import { Z_INDEX } from 'theme/zIndex'
import { isIOS } from 'utils/userAgent' import { isIOS } from 'utils/userAgent'
import bannerImageDark from '../../assets/images/uniswapWalletBannerDark.png' import { ReactComponent as AppleLogo } from '../../assets/svg/apple_logo.svg'
import bannerImageLight from '../../assets/images/uniswapWalletBannerLight.png' import walletBannerPhoneImageSrc from '../../assets/svg/wallet_banner_phone_image.svg'
const PopupContainer = styled.div<{ show: boolean }>` const PopupContainer = styled.div<{ show: boolean }>`
${({ show }) => !show && 'display: none'}; display: flex;
flex-direction: column;
justify-content: space-between;
box-shadow: ${({ theme }) => ${({ show }) => !show && 'display: none'};
theme.darkMode
? '0px -16px 24px rgba(0, 0, 0, 0.4), 0px -8px 12px rgba(0, 0, 0, 0.4), 0px -4px 8px rgba(0, 0, 0, 0.32)'
: '0px -12px 20px rgba(51, 53, 72, 0.04), 0px -6px 12px rgba(51, 53, 72, 0.02), 0px -4px 8px rgba(51, 53, 72, 0.04)'};
background-image: ${({ theme }) => (theme.darkMode ? `url(${bannerImageDark})` : `url(${bannerImageLight})`)}; background: url(${walletBannerPhoneImageSrc});
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: cover; background-position: bottom -1px right 15px;
background-size: 166px;
cursor: pointer; :hover {
background-size: 170px;
}
transition: background-size ${({ theme }) => theme.transition.duration.medium}
${({ theme }) => theme.transition.timing.inOut};
background-color: ${({ theme }) => theme.promotional};
color: ${({ theme }) => theme.textPrimary}; color: ${({ theme }) => theme.textPrimary};
position: fixed; position: fixed;
z-index: ${Z_INDEX.sticky}; z-index: ${Z_INDEX.sticky};
transition: ${({
theme: {
transition: { duration, timing },
},
}) => `${duration.slow} opacity ${timing.in}`};
width: 100%;
bottom: 52px;
height: 20%;
`
const InnerContainer = styled.div` padding: 24px 16px 16px;
overflow: hidden;
display: flex; border-radius: 20px;
flex-direction: column; bottom: 20px;
position: relative; right: 20px;
justify-content: space-between; width: 390px;
height: 100%; height: 164px;
padding: 24px 16px;
border: 1px solid ${({ theme }) => theme.backgroundOutline};
box-shadow: ${({ theme }) => theme.deepShadow};
@media only screen and (max-width: ${({ theme }) => `${theme.breakpoint.md}px`}) {
bottom: 62px;
}
@media only screen and (max-width: ${({ theme }) => `${theme.breakpoint.sm}px`}) {
width: unset;
right: 10px;
left: 10px;
}
user-select: none;
` `
const ButtonRow = styled(Row)` const ButtonRow = styled(Row)`
gap: 16px; gap: 16px;
` `
const StyledXButton = styled(X)` const StyledXButton = styled(X)`
color: ${({ theme }) => theme.textSecondary}; cursor: pointer;
&:hover { position: absolute;
opacity: ${({ theme }) => theme.opacity.hover}; top: 21px;
} right: 17px;
&:active {
opacity: ${({ theme }) => theme.opacity.click}; color: ${({ theme }) => theme.white};
} ${OpacityHoverState};
`
const BannerButton = styled(BaseButton)`
height: 40px;
border-radius: 16px;
padding: 10px;
${OpacityHoverState};
` `
export default function UniswapWalletBanner() { export default function UniswapWalletBanner() {
const [hideUniswapWalletBanner, toggleHideUniswapWalletBanner] = useHideUniswapWalletBanner() const [hideUniswapWalletBanner, toggleHideUniswapWalletBanner] = useHideUniswapWalletBanner()
const [walletDrawerOpen] = useAccountDrawer()
const mgtmEnabled = useMgtmEnabled() const mgtmEnabled = useMgtmEnabled()
const location = useLocation()
const isLandingScreen = location.search === '?intro=true' || location.pathname === '/'
const theme = useTheme() const shouldDisplay = Boolean(mgtmEnabled && !hideUniswapWalletBanner && !isLandingScreen)
const shouldDisplay = Boolean(mgtmEnabled && !walletDrawerOpen && !hideUniswapWalletBanner && isIOS) const screenSize = useScreenSize()
return ( return (
<PopupContainer show={shouldDisplay}> <PopupContainer show={shouldDisplay}>
<InnerContainer>
<AutoColumn gap="8px">
<RowBetween>
<ThemedText.SubHeader>
<Trans>Get the power of Uniswap in your pocket</Trans>
</ThemedText.SubHeader>
<StyledXButton <StyledXButton
data-testid="uniswap-wallet-banner" data-testid="uniswap-wallet-banner"
color={theme.textSecondary}
size={20} size={20}
onClick={(e) => { onClick={(e) => {
// prevent click from bubbling to UI on the page underneath, i.e. clicking a token row
e.preventDefault() e.preventDefault()
e.stopPropagation() e.stopPropagation()
toggleHideUniswapWalletBanner() toggleHideUniswapWalletBanner()
}} }}
/> />
</RowBetween>
<ThemedText.BodySmall> <AutoColumn gap="8px">
<Trans>Download in the App Store today.</Trans>{' '} <ThemedText.HeadlineMedium fontSize="24px" lineHeight="28px" color="white" maxWidth="60%">
</ThemedText.BodySmall> <Trans>Uniswap in your pocket</Trans>
</ThemedText.HeadlineMedium>
</AutoColumn> </AutoColumn>
<ButtonRow> <ButtonRow>
<LearnMoreButton /> {isIOS ? (
<DownloadButton <>
onClick={() => toggleHideUniswapWalletBanner()} <BannerButton
element={InterfaceElementName.UNISWAP_WALLET_BANNER_DOWNLOAD_BUTTON} backgroundColor="white"
/> onClick={() => openDownloadApp(InterfaceElementName.UNISWAP_WALLET_BANNER_DOWNLOAD_BUTTON)}
>
<AppleLogo width={14} height={14} />
<ThemedText.LabelSmall color="black" marginLeft="5px">
{!screenSize['xs'] ? <Trans>Download</Trans> : <Trans>Download app</Trans>}
</ThemedText.LabelSmall>
</BannerButton>
<BannerButton backgroundColor="black" onClick={openWalletMicrosite}>
<ThemedText.LabelSmall color="white">
<Trans>Learn more</Trans>
</ThemedText.LabelSmall>
</BannerButton>
</>
) : (
<BannerButton backgroundColor="white" width="125px" onClick={openWalletMicrosite}>
<ThemedText.LabelSmall color="black">
<Trans>Learn more</Trans>
</ThemedText.LabelSmall>
</BannerButton>
)}
</ButtonRow> </ButtonRow>
</InnerContainer>
</PopupContainer> </PopupContainer>
) )
} }
import { t, Trans } from '@lingui/macro' import { t, Trans } from '@lingui/macro'
import { InterfaceElementName } from '@uniswap/analytics-events'
import { openDownloadApp } from 'components/AccountDrawer/DownloadButton'
import FeatureFlagModal from 'components/FeatureFlagModal/FeatureFlagModal' import FeatureFlagModal from 'components/FeatureFlagModal/FeatureFlagModal'
import { PrivacyPolicyModal } from 'components/PrivacyPolicy' import { PrivacyPolicyModal } from 'components/PrivacyPolicy'
import { useMgtmEnabled } from 'featureFlags/flags/mgtm'
import { useOnClickOutside } from 'hooks/useOnClickOutside' import { useOnClickOutside } from 'hooks/useOnClickOutside'
import { Box } from 'nft/components/Box' import { Box } from 'nft/components/Box'
import { Column, Row } from 'nft/components/Flex' import { Column, Row } from 'nft/components/Flex'
...@@ -21,6 +24,7 @@ import { useToggleModal } from 'state/application/hooks' ...@@ -21,6 +24,7 @@ import { useToggleModal } from 'state/application/hooks'
import styled, { useTheme } from 'styled-components/macro' import styled, { useTheme } from 'styled-components/macro'
import { isDevelopmentEnv, isStagingEnv } from 'utils/env' import { isDevelopmentEnv, isStagingEnv } from 'utils/env'
import { ReactComponent as AppleLogo } from '../../assets/svg/apple_logo.svg'
import { ApplicationModal } from '../../state/application/reducer' import { ApplicationModal } from '../../state/application/reducer'
import * as styles from './MenuDropdown.css' import * as styles from './MenuDropdown.css'
import { NavDropdown } from './NavDropdown' import { NavDropdown } from './NavDropdown'
...@@ -126,6 +130,8 @@ export const MenuDropdown = () => { ...@@ -126,6 +130,8 @@ export const MenuDropdown = () => {
const ref = useRef<HTMLDivElement>(null) const ref = useRef<HTMLDivElement>(null)
useOnClickOutside(ref, isOpen ? toggleOpen : undefined) useOnClickOutside(ref, isOpen ? toggleOpen : undefined)
const mgtmEnabled = useMgtmEnabled()
return ( return (
<> <>
<Box position="relative" ref={ref}> <Box position="relative" ref={ref}>
...@@ -140,16 +146,29 @@ export const MenuDropdown = () => { ...@@ -140,16 +146,29 @@ export const MenuDropdown = () => {
<Box display={{ sm: 'none', lg: 'flex', xxl: 'none' }}> <Box display={{ sm: 'none', lg: 'flex', xxl: 'none' }}>
<PrimaryMenuRow to="/pool" close={toggleOpen}> <PrimaryMenuRow to="/pool" close={toggleOpen}>
<Icon> <Icon>
<PoolIcon width={24} height={24} color={theme.textSecondary} /> <PoolIcon width={24} height={24} fill={theme.textPrimary} />
</Icon> </Icon>
<PrimaryMenuRow.Text> <PrimaryMenuRow.Text>
<Trans>Pool</Trans> <Trans>Pool</Trans>
</PrimaryMenuRow.Text> </PrimaryMenuRow.Text>
</PrimaryMenuRow> </PrimaryMenuRow>
</Box> </Box>
<Box
display={mgtmEnabled ? 'flex' : 'none'}
onClick={() => openDownloadApp(InterfaceElementName.UNISWAP_WALLET_MODAL_DOWNLOAD_BUTTON)}
>
<PrimaryMenuRow close={toggleOpen}>
<Icon>
<AppleLogo width="24px" height="24px" fill={theme.textPrimary} />
</Icon>
<PrimaryMenuRow.Text>
<Trans>Download Uniswap Wallet</Trans>
</PrimaryMenuRow.Text>
</PrimaryMenuRow>
</Box>
<PrimaryMenuRow to="/vote" close={toggleOpen}> <PrimaryMenuRow to="/vote" close={toggleOpen}>
<Icon> <Icon>
<GovernanceIcon width={24} height={24} color={theme.textSecondary} /> <GovernanceIcon width={24} height={24} color={theme.textPrimary} />
</Icon> </Icon>
<PrimaryMenuRow.Text> <PrimaryMenuRow.Text>
<Trans>Vote in governance</Trans> <Trans>Vote in governance</Trans>
...@@ -157,7 +176,7 @@ export const MenuDropdown = () => { ...@@ -157,7 +176,7 @@ export const MenuDropdown = () => {
</PrimaryMenuRow> </PrimaryMenuRow>
<PrimaryMenuRow href="https://info.uniswap.org/#/"> <PrimaryMenuRow href="https://info.uniswap.org/#/">
<Icon> <Icon>
<BarChartIcon width={24} height={24} color={theme.textSecondary} /> <BarChartIcon width={24} height={24} color={theme.textPrimary} />
</Icon> </Icon>
<PrimaryMenuRow.Text> <PrimaryMenuRow.Text>
<Trans>View more analytics</Trans> <Trans>View more analytics</Trans>
......
...@@ -83,6 +83,7 @@ export const colors = { ...@@ -83,6 +83,7 @@ export const colors = {
blue900: '#040E34', blue900: '#040E34',
blueVibrant: '#587BFF', blueVibrant: '#587BFF',
// TODO: add magenta 50-900 // TODO: add magenta 50-900
magenta300: '#FD82FF',
magentaVibrant: '#FC72FF', magentaVibrant: '#FC72FF',
purple300: '#8440F2', purple300: '#8440F2',
purple900: '#1C0337', purple900: '#1C0337',
...@@ -119,6 +120,7 @@ const commonTheme = { ...@@ -119,6 +120,7 @@ const commonTheme = {
chain_10_background: colors.red900, chain_10_background: colors.red900,
chain_42161_background: colors.blue900, chain_42161_background: colors.blue900,
chain_56_background: colors.networkBsc, chain_56_background: colors.networkBsc,
promotional: colors.magenta300,
brandedGradient: 'linear-gradient(139.57deg, #FF79C9 4.35%, #FFB8E2 96.44%);', brandedGradient: 'linear-gradient(139.57deg, #FF79C9 4.35%, #FFB8E2 96.44%);',
promotionalGradient: 'radial-gradient(101.8% 4091.31% at 0% 0%, #4673FA 0%, #9646FA 100%);', promotionalGradient: 'radial-gradient(101.8% 4091.31% at 0% 0%, #4673FA 0%, #9646FA 100%);',
......
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