Commit 0b8026e6 authored by Jordan Frankfurt's avatar Jordan Frankfurt Committed by GitHub

feat: add base promotional advert (#7124)

* feat: add base promotional advert

add mobile layout

tweak text container size

only show new banner on Base

fix import

update to new state structure

* Update src/components/Banner/BaseAnnouncementBanner/index.tsx
Co-authored-by: default avatarCharles Bachmeier <charles@bachmeier.io>

* pr feedback

---------
Co-authored-by: default avatarCharles Bachmeier <charles@bachmeier.io>
parent b14831be
<svg width="119" height="99" viewBox="0 0 119 99" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M118.097 29.6061C117.891 67.6376 86.8404 98.3016 48.7425 98.0958C12.5975 97.9006 -16.9048 69.9894 -19.659 34.6507L71.5199 35.1431L71.5825 23.5662L-19.5965 23.0738C-16.4608 -12.2332 13.3412 -39.824 49.4863 -39.6288C87.5842 -39.423 118.302 -8.4256 118.097 29.6061Z" fill="white" fill-opacity="0.1"/>
</svg>
import { Trans } from '@lingui/macro' import { Trans } from '@lingui/macro'
import { InterfaceElementName } from '@uniswap/analytics-events' import { InterfaceElementName } from '@uniswap/analytics-events'
import walletBannerPhoneImageSrc from 'assets/images/wallet_banner_phone_image.png' import { ChainId } from '@uniswap/sdk-core'
import { useWeb3React } from '@web3-react/core'
import { ReactComponent as AppleLogo } from 'assets/svg/apple_logo.svg' import { ReactComponent as AppleLogo } from 'assets/svg/apple_logo.svg'
import { BaseButton } from 'components/Button' import baseLogoUrl from 'assets/svg/base_background_icon.svg'
import { AutoColumn } from 'components/Column'
import { OpacityHoverState } from 'components/Common'
import Row from 'components/Row'
import { useScreenSize } from 'hooks/useScreenSize' import { useScreenSize } from 'hooks/useScreenSize'
import { X } from 'react-feather'
import { useLocation } from 'react-router-dom' import { useLocation } from 'react-router-dom'
import { useHideUniswapWalletBanner } from 'state/user/hooks' import { useHideBaseWalletBanner } from 'state/user/hooks'
import styled from 'styled-components'
import { ThemedText } from 'theme' import { ThemedText } from 'theme'
import { Z_INDEX } from 'theme/zIndex'
import { openDownloadApp, openWalletMicrosite } from 'utils/openDownloadApp' import { openDownloadApp, openWalletMicrosite } from 'utils/openDownloadApp'
import { isIOS, isMobileSafari } from 'utils/userAgent' import { isIOS, isMobileSafari } from 'utils/userAgent'
const PopupContainer = styled.div<{ show: boolean }>` import { BannerButton, BaseBackgroundImage, ButtonRow, PopupContainer, StyledXButton } from './styled'
display: flex;
flex-direction: column;
justify-content: space-between;
${({ show }) => !show && 'display: none'}; export default function BaseWalletBanner() {
const { chainId } = useWeb3React()
background: url(${walletBannerPhoneImageSrc}); const [hideBaseWalletBanner, toggleHideBaseWalletBanner] = useHideBaseWalletBanner()
background-repeat: no-repeat;
background-position: top 18px right 15px;
background-size: 166px;
: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};
position: fixed;
z-index: ${Z_INDEX.sticky};
padding: 24px 16px 16px;
border-radius: 20px;
bottom: 20px;
right: 20px;
width: 390px;
height: 164px;
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)`
gap: 16px;
`
const StyledXButton = styled(X)`
cursor: pointer;
position: absolute;
top: 21px;
right: 17px;
color: ${({ theme }) => theme.white};
${OpacityHoverState};
`
const BannerButton = styled(BaseButton)`
height: 40px;
border-radius: 16px;
padding: 10px;
${OpacityHoverState};
`
export default function UniswapWalletBanner() {
const [hideUniswapWalletBanner, toggleHideUniswapWalletBanner] = useHideUniswapWalletBanner()
const location = useLocation() const location = useLocation()
const isLandingScreen = location.search === '?intro=true' || location.pathname === '/' const isLandingScreen = location.search === '?intro=true' || location.pathname === '/'
const shouldDisplay = Boolean(!hideUniswapWalletBanner && !isLandingScreen) const shouldDisplay = Boolean(!hideBaseWalletBanner && !isLandingScreen && chainId === ChainId.BASE)
const screenSize = useScreenSize() const screenSize = useScreenSize()
...@@ -104,15 +34,26 @@ export default function UniswapWalletBanner() { ...@@ -104,15 +34,26 @@ export default function UniswapWalletBanner() {
// prevent click from bubbling to UI on the page underneath, i.e. clicking a token row // 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() toggleHideBaseWalletBanner()
}} }}
/> />
<AutoColumn gap="8px"> <BaseBackgroundImage src={baseLogoUrl} alt="transparent base background logo" />
<ThemedText.HeadlineMedium fontSize="24px" lineHeight="28px" color="white" maxWidth="60%">
<Trans>Uniswap in your pocket</Trans> <ThemedText.HeadlineMedium fontSize="24px" lineHeight="28px" color="white" maxWidth="224px">
</ThemedText.HeadlineMedium> <Trans>
</AutoColumn> Swap on{' '}
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M19.5689 10C19.5689 15.4038 15.1806 19.7845 9.76737 19.7845C4.63163 19.7845 0.418433 15.8414 0 10.8225H12.9554V9.17755H0C0.418433 4.15863 4.63163 0.215576 9.76737 0.215576C15.1806 0.215576 19.5689 4.59621 19.5689 10Z"
fill="white"
/>
</svg>{' '}
BASE in the Uniswap wallet
</Trans>
</ThemedText.HeadlineMedium>
<ButtonRow> <ButtonRow>
{isIOS ? ( {isIOS ? (
...@@ -122,6 +63,7 @@ export default function UniswapWalletBanner() { ...@@ -122,6 +63,7 @@ export default function UniswapWalletBanner() {
onClick={() => onClick={() =>
openDownloadApp({ openDownloadApp({
element: InterfaceElementName.UNISWAP_WALLET_BANNER_DOWNLOAD_BUTTON, element: InterfaceElementName.UNISWAP_WALLET_BANNER_DOWNLOAD_BUTTON,
appStoreParams: 'pt=123625782&ct=base-app-banner&mt=8',
}) })
} }
> >
......
import walletBannerPhoneImageSrc from 'assets/images/wallet_banner_phone_image.png'
import { BaseButton } from 'components/Button'
import { OpacityHoverState } from 'components/Common'
import Row from 'components/Row'
import { X } from 'react-feather'
import styled from 'styled-components'
import { Z_INDEX } from 'theme/zIndex'
export const PopupContainer = styled.div<{ show: boolean }>`
display: flex;
flex-direction: column;
justify-content: space-between;
${({ show }) => !show && 'display: none'};
background: url(${walletBannerPhoneImageSrc});
background-repeat: no-repeat;
background-position: top 18px right 15px;
background-size: 166px;
:hover {
background-size: 170px;
}
transition: background-size ${({ theme }) => theme.transition.duration.medium}
${({ theme }) => theme.transition.timing.inOut};
background-color: ${({ theme }) => theme.chain_84531};
color: ${({ theme }) => theme.textPrimary};
position: fixed;
z-index: ${Z_INDEX.sticky};
padding: 24px 16px 16px;
border-radius: 20px;
bottom: 20px;
right: 20px;
width: 390px;
height: 164px;
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`}) {
background-position: top 32px right -10px;
width: unset;
right: 10px;
left: 10px;
height: 144px;
}
user-select: none;
`
export const BaseBackgroundImage = styled.img`
position: absolute;
top: 0;
left: 0;
height: 138px;
width: 138px;
`
export const ButtonRow = styled(Row)`
gap: 16px;
`
export const StyledXButton = styled(X)`
cursor: pointer;
position: absolute;
top: 21px;
right: 17px;
color: ${({ theme }) => theme.white};
${OpacityHoverState};
`
export const BannerButton = styled(BaseButton)`
height: 40px;
border-radius: 16px;
padding: 10px;
${OpacityHoverState};
`
import { useWeb3React } from '@web3-react/core' import { useWeb3React } from '@web3-react/core'
import { OffchainActivityModal } from 'components/AccountDrawer/MiniPortfolio/Activity/OffchainActivityModal' import { OffchainActivityModal } from 'components/AccountDrawer/MiniPortfolio/Activity/OffchainActivityModal'
import UniwalletModal from 'components/AccountDrawer/UniwalletModal' import UniwalletModal from 'components/AccountDrawer/UniwalletModal'
import UniswapWalletBanner from 'components/Banner/UniswapWalletBanner' import BaseAnnouncementBanner from 'components/Banner/BaseAnnouncementBanner'
import AddressClaimModal from 'components/claim/AddressClaimModal' import AddressClaimModal from 'components/claim/AddressClaimModal'
import ConnectedAccountBlocked from 'components/ConnectedAccountBlocked' import ConnectedAccountBlocked from 'components/ConnectedAccountBlocked'
import FiatOnrampModal from 'components/FiatOnrampModal' import FiatOnrampModal from 'components/FiatOnrampModal'
...@@ -28,7 +28,7 @@ export default function TopLevelModals() { ...@@ -28,7 +28,7 @@ export default function TopLevelModals() {
<ConnectedAccountBlocked account={account} isOpen={accountBlocked} /> <ConnectedAccountBlocked account={account} isOpen={accountBlocked} />
<Bag /> <Bag />
<UniwalletModal /> <UniwalletModal />
<UniswapWalletBanner /> <BaseAnnouncementBanner />
<OffchainActivityModal /> <OffchainActivityModal />
<TransactionCompleteModal /> <TransactionCompleteModal />
<AirdropModal /> <AirdropModal />
......
...@@ -16,8 +16,8 @@ import { AppState } from '../types' ...@@ -16,8 +16,8 @@ import { AppState } from '../types'
import { import {
addSerializedPair, addSerializedPair,
addSerializedToken, addSerializedToken,
updateHideBaseWalletBanner,
updateHideClosedPositions, updateHideClosedPositions,
updateHideUniswapWalletBanner,
updateUserDeadline, updateUserDeadline,
updateUserLocale, updateUserLocale,
updateUserRouterPreference, updateUserRouterPreference,
...@@ -211,15 +211,15 @@ export function useURLWarningVisible(): boolean { ...@@ -211,15 +211,15 @@ export function useURLWarningVisible(): boolean {
return useAppSelector((state: AppState) => state.user.URLWarningVisible) return useAppSelector((state: AppState) => state.user.URLWarningVisible)
} }
export function useHideUniswapWalletBanner(): [boolean, () => void] { export function useHideBaseWalletBanner(): [boolean, () => void] {
const dispatch = useAppDispatch() const dispatch = useAppDispatch()
const hideUniswapWalletBanner = useAppSelector((state) => state.user.hideUniswapWalletBanner) const hideBaseWalletBanner = useAppSelector((state) => state.user.hideBaseWalletBanner)
const toggleHideUniswapWalletBanner = useCallback(() => { const toggleHideBaseWalletBanner = useCallback(() => {
dispatch(updateHideUniswapWalletBanner({ hideUniswapWalletBanner: true })) dispatch(updateHideBaseWalletBanner({ hideBaseWalletBanner: true }))
}, [dispatch]) }, [dispatch])
return [hideUniswapWalletBanner, toggleHideUniswapWalletBanner] return [hideBaseWalletBanner, toggleHideBaseWalletBanner]
} }
export function useUserDisabledUniswapX(): boolean { export function useUserDisabledUniswapX(): boolean {
......
...@@ -7,8 +7,8 @@ import reducer, { ...@@ -7,8 +7,8 @@ import reducer, {
addSerializedPair, addSerializedPair,
addSerializedToken, addSerializedToken,
initialState, initialState,
updateHideBaseWalletBanner,
updateHideClosedPositions, updateHideClosedPositions,
updateHideUniswapWalletBanner,
updateSelectedWallet, updateSelectedWallet,
updateUserDeadline, updateUserDeadline,
updateUserLocale, updateUserLocale,
...@@ -110,10 +110,10 @@ describe('swap reducer', () => { ...@@ -110,10 +110,10 @@ describe('swap reducer', () => {
}) })
}) })
describe('updateHideUniswapWalletBanner', () => { describe('updateHideBaseWalletBanner', () => {
it('updates the hideUniswapWalletBanner', () => { it('updates the updateHideBaseWalletBanner', () => {
store.dispatch(updateHideUniswapWalletBanner({ hideUniswapWalletBanner: true })) store.dispatch(updateHideBaseWalletBanner({ hideBaseWalletBanner: true }))
expect(store.getState().hideUniswapWalletBanner).toEqual(true) expect(store.getState().hideBaseWalletBanner).toEqual(true)
}) })
}) })
......
...@@ -47,7 +47,7 @@ export interface UserState { ...@@ -47,7 +47,7 @@ export interface UserState {
timestamp: number timestamp: number
URLWarningVisible: boolean URLWarningVisible: boolean
hideUniswapWalletBanner: boolean hideBaseWalletBanner: boolean
disabledUniswapX?: boolean disabledUniswapX?: boolean
// undefined means has not gone through A/B split yet // undefined means has not gone through A/B split yet
showSurveyPopup?: boolean showSurveyPopup?: boolean
...@@ -69,7 +69,7 @@ export const initialState: UserState = { ...@@ -69,7 +69,7 @@ export const initialState: UserState = {
pairs: {}, pairs: {},
timestamp: currentTimestamp(), timestamp: currentTimestamp(),
URLWarningVisible: true, URLWarningVisible: true,
hideUniswapWalletBanner: false, hideBaseWalletBanner: false,
showSurveyPopup: undefined, showSurveyPopup: undefined,
} }
...@@ -98,8 +98,8 @@ const userSlice = createSlice({ ...@@ -98,8 +98,8 @@ const userSlice = createSlice({
updateHideClosedPositions(state, action) { updateHideClosedPositions(state, action) {
state.userHideClosedPositions = action.payload.userHideClosedPositions state.userHideClosedPositions = action.payload.userHideClosedPositions
}, },
updateHideUniswapWalletBanner(state, action) { updateHideBaseWalletBanner(state, action) {
state.hideUniswapWalletBanner = action.payload.hideUniswapWalletBanner state.hideBaseWalletBanner = action.payload.hideBaseWalletBanner
}, },
updateDisabledUniswapX(state, action) { updateDisabledUniswapX(state, action) {
state.disabledUniswapX = action.payload.disabledUniswapX state.disabledUniswapX = action.payload.disabledUniswapX
...@@ -214,7 +214,7 @@ export const { ...@@ -214,7 +214,7 @@ export const {
updateUserDeadline, updateUserDeadline,
updateUserLocale, updateUserLocale,
updateUserSlippageTolerance, updateUserSlippageTolerance,
updateHideUniswapWalletBanner, updateHideBaseWalletBanner,
updateDisabledUniswapX, updateDisabledUniswapX,
} = userSlice.actions } = userSlice.actions
export default userSlice.reducer export default userSlice.reducer
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