From 395b390df67b2d4554e0432d559cba2a85ca321c Mon Sep 17 00:00:00 2001 From: Kristie Huang Date: Wed, 8 Nov 2023 16:18:16 -0500 Subject: [PATCH] feat: add android announcement banner (#7551) * feat [wip]: add android announcement banner * feat: [wip] add android announcement banner * finish css * remove hideBaseWallet references * phil changes * minor lint nit * pr review * growth copy --- .../images/AndroidWallet-Thumbnail-Dark.png | Bin 0 -> 11256 bytes .../images/AndroidWallet-Thumbnail-Light.png | Bin 0 -> 10061 bytes .../images/androidAnnouncementBannerQR.png | Bin 0 -> 1197 bytes .../AccountDrawer/UniwalletModal.tsx | 4 +- .../AndroidAnnouncementBanner/index.tsx | 72 ++++++++++++ .../AndroidAnnouncementBanner/styled.tsx | 92 +++++++++++++++ .../Banner/BaseAnnouncementBanner/index.tsx | 105 ------------------ .../Banner/BaseAnnouncementBanner/styled.tsx | 84 -------------- src/components/TopLevelModals/index.tsx | 4 +- src/state/migrations/1.test.ts | 3 +- src/state/migrations/2.test.ts | 2 +- src/state/migrations/3.test.ts | 2 +- src/state/reducerTypeTest.ts | 2 +- src/state/user/hooks.tsx | 12 +- src/state/user/reducer.test.ts | 10 +- src/state/user/reducer.ts | 10 +- src/utils/openDownloadApp.ts | 8 +- 17 files changed, 190 insertions(+), 220 deletions(-) create mode 100644 src/assets/images/AndroidWallet-Thumbnail-Dark.png create mode 100644 src/assets/images/AndroidWallet-Thumbnail-Light.png create mode 100644 src/assets/images/androidAnnouncementBannerQR.png create mode 100644 src/components/Banner/AndroidAnnouncementBanner/index.tsx create mode 100644 src/components/Banner/AndroidAnnouncementBanner/styled.tsx delete mode 100644 src/components/Banner/BaseAnnouncementBanner/index.tsx delete mode 100644 src/components/Banner/BaseAnnouncementBanner/styled.tsx diff --git a/src/assets/images/AndroidWallet-Thumbnail-Dark.png b/src/assets/images/AndroidWallet-Thumbnail-Dark.png new file mode 100644 index 0000000000000000000000000000000000000000..2fc3706a073ece532715db9832997114f0006869 GIT binary patch literal 11256 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 - Don't have Uniswap Wallet? + Don't have a Uniswap wallet? {isAndroidGALaunched ? ( - Get the Uniswap app on iOS and Android to safely store and swap tokens. + Safely store and swap tokens with the Uniswap app. Available on iOS and Android. ) : ( Download in the App Store to safely store your tokens and NFTs, swap tokens, and connect to crypto apps. diff --git a/src/components/Banner/AndroidAnnouncementBanner/index.tsx b/src/components/Banner/AndroidAnnouncementBanner/index.tsx new file mode 100644 index 0000000000..2902aa6a44 --- /dev/null +++ b/src/components/Banner/AndroidAnnouncementBanner/index.tsx @@ -0,0 +1,72 @@ +import { Trans } from '@lingui/macro' +import { InterfaceElementName } from '@uniswap/analytics-events' +import { useAndroidGALaunchFlagEnabled } from 'featureFlags/flags/androidGALaunch' +import { useScreenSize } from 'hooks/useScreenSize' +import { useLocation } from 'react-router-dom' +import { useHideAndroidAnnouncementBanner } from 'state/user/hooks' +import { ThemedText } from 'theme/components' +import { useIsDarkMode } from 'theme/components/ThemeToggle' +import { openDownloadApp } from 'utils/openDownloadApp' +import { isMobileSafari } from 'utils/userAgent' + +import androidAnnouncementBannerQR from '../../../assets/images/androidAnnouncementBannerQR.png' +import darkAndroidThumbnail from '../../../assets/images/AndroidWallet-Thumbnail-Dark.png' +import lightAndroidThumbnail from '../../../assets/images/AndroidWallet-Thumbnail-Light.png' +import { + Container, + DownloadButton, + PopupContainer, + StyledQrCode, + StyledXButton, + TextContainer, + Thumbnail, +} from './styled' + +export default function AndroidAnnouncementBanner() { + const [hideAndroidAnnouncementBanner, toggleHideAndroidAnnouncementBanner] = useHideAndroidAnnouncementBanner() + const location = useLocation() + const isLandingScreen = location.search === '?intro=true' || location.pathname === '/' + const screenSize = useScreenSize() + + const shouldDisplay = Boolean(!hideAndroidAnnouncementBanner && !isLandingScreen) + const isDarkMode = useIsDarkMode() + + const isAndroidGALaunched = useAndroidGALaunchFlagEnabled() + const onClick = () => + openDownloadApp({ + element: InterfaceElementName.UNISWAP_WALLET_BANNER_DOWNLOAD_BUTTON, + isAndroidGALaunched, + }) + + if (!isAndroidGALaunched || isMobileSafari) return null + + return ( + + + + + + Uniswap on Android + + + Available now - download from the Google Play Store today + + + Download now + + + + { + // prevent click from bubbling to UI on the page underneath, i.e. clicking a token row + e.preventDefault() + e.stopPropagation() + toggleHideAndroidAnnouncementBanner() + }} + /> + + + ) +} diff --git a/src/components/Banner/AndroidAnnouncementBanner/styled.tsx b/src/components/Banner/AndroidAnnouncementBanner/styled.tsx new file mode 100644 index 0000000000..a635746f5a --- /dev/null +++ b/src/components/Banner/AndroidAnnouncementBanner/styled.tsx @@ -0,0 +1,92 @@ +import { ButtonText } from 'components/Button' +import { OpacityHoverState } from 'components/Common' +import { X } from 'react-feather' +import styled from 'styled-components' +import { BREAKPOINTS } from 'theme' +import { Z_INDEX } from 'theme/zIndex' + +export const PopupContainer = styled.div<{ show: boolean }>` + ${({ show }) => !show && 'display: none'}; + background-color: ${({ theme }) => theme.surface2}; + color: ${({ theme }) => theme.neutral1}; + position: fixed; + z-index: ${Z_INDEX.sticky}; + user-select: none; + border-radius: 20px; + bottom: 40px; + right: 20px; + width: 360px; + height: 92px; + border: 1.3px solid ${({ theme }) => theme.surface3}; + + @media only screen and (max-width: ${BREAKPOINTS.md}px) { + bottom: 62px; + } + + @media only screen and (max-width: ${BREAKPOINTS.xs}px) { + width: unset; + right: 10px; + left: 10px; + } +` +export const StyledXButton = styled(X)` + cursor: pointer; + position: absolute; + top: -30px; + right: 0px; + padding: 4px; + border-radius: 50%; + + background-color: ${({ theme }) => theme.surface5}; + color: ${({ theme }) => theme.neutral2}; + ${OpacityHoverState}; + + @media only screen and (max-width: ${BREAKPOINTS.xs}px) { + top: 8px; + right: 8px; + } +` + +export const Container = styled.div` + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + height: 100%; + overflow: hidden; + border-radius: 20px; + gap: 16px; +` +export const Thumbnail = styled.img` + width: 82px; +` +export const TextContainer = styled.div` + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 2px; + color: ${({ theme }) => theme.neutral2}; + padding: 10px 0px 10px; + line-height: 16px; + + @media only screen and (max-width: ${BREAKPOINTS.xs}px) { + width: 220px; + } +` +export const StyledQrCode = styled.img` + padding: 2px; + border-radius: 8px; + width: 64px; + height: 64px; + background-color: ${({ theme }) => theme.white}; + margin-right: 16px; + + @media only screen and (max-width: ${BREAKPOINTS.xs}px) { + display: none; + } +` +export const DownloadButton = styled(ButtonText)` + line-height: 16px; + font-size: 14px; + color: ${({ theme }) => theme.accent1}; +` diff --git a/src/components/Banner/BaseAnnouncementBanner/index.tsx b/src/components/Banner/BaseAnnouncementBanner/index.tsx deleted file mode 100644 index e092b4e364..0000000000 --- a/src/components/Banner/BaseAnnouncementBanner/index.tsx +++ /dev/null @@ -1,105 +0,0 @@ -import { Trans } from '@lingui/macro' -import { InterfaceElementName } from '@uniswap/analytics-events' -import { ChainId } from '@uniswap/sdk-core' -import { useWeb3React } from '@web3-react/core' -import { ReactComponent as AppleLogo } from 'assets/svg/apple_logo.svg' -import baseLogoUrl from 'assets/svg/base_background_icon.svg' -import { ReactComponent as UniswapAppLogo } from 'assets/svg/uniswap_app_logo.svg' -import { useAndroidGALaunchFlagEnabled } from 'featureFlags/flags/androidGALaunch' -import { useScreenSize } from 'hooks/useScreenSize' -import { useLocation } from 'react-router-dom' -import { useHideBaseWalletBanner } from 'state/user/hooks' -import { ThemedText } from 'theme/components' -import { openDownloadApp, openWalletMicrosite } from 'utils/openDownloadApp' -import { isAndroid, isIOS, isMobileSafari } from 'utils/userAgent' - -import { BannerButton, BaseBackgroundImage, ButtonRow, PopupContainer, StyledXButton } from './styled' - -export default function BaseWalletBanner() { - const { chainId } = useWeb3React() - const [hideBaseWalletBanner, toggleHideBaseWalletBanner] = useHideBaseWalletBanner() - const location = useLocation() - const isLandingScreen = location.search === '?intro=true' || location.pathname === '/' - - const shouldDisplay = Boolean(!hideBaseWalletBanner && !isLandingScreen && chainId === ChainId.BASE) - - const screenSize = useScreenSize() - - const isAndroidGALaunched = useAndroidGALaunchFlagEnabled() - - if (isMobileSafari) return null - - return ( - - { - // prevent click from bubbling to UI on the page underneath, i.e. clicking a token row - e.preventDefault() - e.stopPropagation() - toggleHideBaseWalletBanner() - }} - /> - - - - - - Swap on{' '} - - - {' '} - BASE in the Uniswap wallet - - - - - {isIOS || (isAndroidGALaunched && isAndroid) ? ( - <> - - openDownloadApp({ - element: InterfaceElementName.UNISWAP_WALLET_BANNER_DOWNLOAD_BUTTON, - isAndroidGALaunched, - }) - } - > - {isAndroidGALaunched ? : } - - {!screenSize['xs'] ? Download : Download app} - - - - - openWalletMicrosite({ element: InterfaceElementName.UNISWAP_WALLET_BANNER_DOWNLOAD_BUTTON }) - } - > - - Learn more - - - - ) : ( - openWalletMicrosite({ element: InterfaceElementName.UNISWAP_WALLET_BANNER_DOWNLOAD_BUTTON })} - > - - Learn more - - - )} - - - ) -} diff --git a/src/components/Banner/BaseAnnouncementBanner/styled.tsx b/src/components/Banner/BaseAnnouncementBanner/styled.tsx deleted file mode 100644 index b96cf72bed..0000000000 --- a/src/components/Banner/BaseAnnouncementBanner/styled.tsx +++ /dev/null @@ -1,84 +0,0 @@ -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.neutral1}; - 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.surface3}; - - box-shadow: ${({ theme }) => theme.deprecated_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}; -` diff --git a/src/components/TopLevelModals/index.tsx b/src/components/TopLevelModals/index.tsx index cdf4540254..a62f3cce0e 100644 --- a/src/components/TopLevelModals/index.tsx +++ b/src/components/TopLevelModals/index.tsx @@ -2,7 +2,7 @@ import { useWeb3React } from '@web3-react/core' import { OffchainActivityModal } from 'components/AccountDrawer/MiniPortfolio/Activity/OffchainActivityModal' import UniwalletModal from 'components/AccountDrawer/UniwalletModal' import AirdropModal from 'components/AirdropModal' -import BaseAnnouncementBanner from 'components/Banner/BaseAnnouncementBanner' +import AndroidAnnouncementBanner from 'components/Banner/AndroidAnnouncementBanner' import AddressClaimModal from 'components/claim/AddressClaimModal' import ConnectedAccountBlocked from 'components/ConnectedAccountBlocked' import FiatOnrampModal from 'components/FiatOnrampModal' @@ -30,7 +30,7 @@ export default function TopLevelModals() { - + diff --git a/src/state/migrations/1.test.ts b/src/state/migrations/1.test.ts index 30c77054f4..32ed481111 100644 --- a/src/state/migrations/1.test.ts +++ b/src/state/migrations/1.test.ts @@ -15,7 +15,7 @@ const previousState: PersistAppStateV1 = { tokens: {}, pairs: {}, timestamp: Date.now(), - hideBaseWalletBanner: false, + hideAndroidAnnouncementBanner: false, }, _persist: { version: 0, @@ -43,7 +43,6 @@ describe('migration to v1', () => { expect(result?.user?.tokens).toEqual({}) expect(result?.user?.pairs).toEqual({}) expect(result?.user?.timestamp).toEqual(previousState.user?.timestamp) - expect(result?.user?.hideBaseWalletBanner).toEqual(false) }) it('should not migrate a non-default value', async () => { diff --git a/src/state/migrations/2.test.ts b/src/state/migrations/2.test.ts index 4945c82402..9560ac3687 100644 --- a/src/state/migrations/2.test.ts +++ b/src/state/migrations/2.test.ts @@ -17,7 +17,7 @@ const previousState: PersistAppStateV2 = { tokens: {}, pairs: {}, timestamp: Date.now(), - hideBaseWalletBanner: false, + hideAndroidAnnouncementBanner: false, }, _persist: { version: 1, diff --git a/src/state/migrations/3.test.ts b/src/state/migrations/3.test.ts index 9d8437653d..1317ac2445 100644 --- a/src/state/migrations/3.test.ts +++ b/src/state/migrations/3.test.ts @@ -38,7 +38,7 @@ const previousState: PersistAppStateV3 = { }, pairs: {}, timestamp: Date.now(), - hideBaseWalletBanner: false, + hideAndroidAnnouncementBanner: false, }, _persist: { version: 2, diff --git a/src/state/reducerTypeTest.ts b/src/state/reducerTypeTest.ts index 5aadb43231..fd32c3bbe7 100644 --- a/src/state/reducerTypeTest.ts +++ b/src/state/reducerTypeTest.ts @@ -87,7 +87,7 @@ interface ExpectedUserState { } } timestamp: number - hideBaseWalletBanner: boolean + hideAndroidAnnouncementBanner: boolean showSurveyPopup?: boolean disabledUniswapX?: boolean optedOutOfUniswapX?: boolean diff --git a/src/state/user/hooks.tsx b/src/state/user/hooks.tsx index 793e0f1bd7..5072b4da4f 100644 --- a/src/state/user/hooks.tsx +++ b/src/state/user/hooks.tsx @@ -15,7 +15,7 @@ import { useDefaultActiveTokens } from '../../hooks/Tokens' import { addSerializedPair, addSerializedToken, - updateHideBaseWalletBanner, + updateHideAndroidAnnouncementBanner, updateHideClosedPositions, updateUserDeadline, updateUserLocale, @@ -206,15 +206,15 @@ export function usePairAdder(): (pair: Pair) => void { ) } -export function useHideBaseWalletBanner(): [boolean, () => void] { +export function useHideAndroidAnnouncementBanner(): [boolean, () => void] { const dispatch = useAppDispatch() - const hideBaseWalletBanner = useAppSelector((state) => state.user.hideBaseWalletBanner) + const hideAndroidAnnouncementBanner = useAppSelector((state) => state.user.hideAndroidAnnouncementBanner) - const toggleHideBaseWalletBanner = useCallback(() => { - dispatch(updateHideBaseWalletBanner({ hideBaseWalletBanner: true })) + const toggleHideAndroidAnnouncementBanner = useCallback(() => { + dispatch(updateHideAndroidAnnouncementBanner({ hideAndroidAnnouncementBanner: true })) }, [dispatch]) - return [hideBaseWalletBanner, toggleHideBaseWalletBanner] + return [hideAndroidAnnouncementBanner, toggleHideAndroidAnnouncementBanner] } export function useUserDisabledUniswapX(): boolean { diff --git a/src/state/user/reducer.test.ts b/src/state/user/reducer.test.ts index 893dfa719d..67731cd385 100644 --- a/src/state/user/reducer.test.ts +++ b/src/state/user/reducer.test.ts @@ -5,7 +5,7 @@ import reducer, { addSerializedPair, addSerializedToken, initialState, - updateHideBaseWalletBanner, + updateHideAndroidAnnouncementBanner, updateHideClosedPositions, updateSelectedWallet, updateUserDeadline, @@ -77,10 +77,10 @@ describe('swap reducer', () => { }) }) - describe('updateHideBaseWalletBanner', () => { - it('updates the updateHideBaseWalletBanner', () => { - store.dispatch(updateHideBaseWalletBanner({ hideBaseWalletBanner: true })) - expect(store.getState().hideBaseWalletBanner).toEqual(true) + describe('updateHideAndroidAnnouncementBanner', () => { + it('updates the updateHideAndroidAnnouncementBanner', () => { + store.dispatch(updateHideAndroidAnnouncementBanner({ hideAndroidAnnouncementBanner: true })) + expect(store.getState().hideAndroidAnnouncementBanner).toEqual(true) }) }) diff --git a/src/state/user/reducer.ts b/src/state/user/reducer.ts index 5e49d56723..4c32ebade7 100644 --- a/src/state/user/reducer.ts +++ b/src/state/user/reducer.ts @@ -47,7 +47,7 @@ export interface UserState { } timestamp: number - hideBaseWalletBanner: boolean + hideAndroidAnnouncementBanner: boolean // legacy field indicating the user disabled UniswapX during the opt-in period, or dismissed the UniswapX opt-in modal. disabledUniswapX?: boolean // temporary field indicating the user disabled UniswapX during the transition to the opt-out model @@ -73,7 +73,7 @@ export const initialState: UserState = { tokens: {}, pairs: {}, timestamp: currentTimestamp(), - hideBaseWalletBanner: false, + hideAndroidAnnouncementBanner: false, showSurveyPopup: undefined, originCountry: undefined, } @@ -108,8 +108,8 @@ const userSlice = createSlice({ updateHideClosedPositions(state, action) { state.userHideClosedPositions = action.payload.userHideClosedPositions }, - updateHideBaseWalletBanner(state, action) { - state.hideBaseWalletBanner = action.payload.hideBaseWalletBanner + updateHideAndroidAnnouncementBanner(state, action) { + state.hideAndroidAnnouncementBanner = action.payload.hideAndroidAnnouncementBanner }, updateDisabledUniswapX(state, action) { state.disabledUniswapX = action.payload.disabledUniswapX @@ -152,7 +152,7 @@ export const { updateUserDeadline, updateUserLocale, updateUserSlippageTolerance, - updateHideBaseWalletBanner, + updateHideAndroidAnnouncementBanner, updateDisabledUniswapX, updateOptedOutOfUniswapX, } = userSlice.actions diff --git a/src/utils/openDownloadApp.ts b/src/utils/openDownloadApp.ts index 4da49ae737..b1d35b0ad6 100644 --- a/src/utils/openDownloadApp.ts +++ b/src/utils/openDownloadApp.ts @@ -34,7 +34,8 @@ export function openDownloadApp({ element, isAndroidGALaunched }: OpenDownloadAp } else if (isAndroidGALaunched && isAndroid) { openDownloadStore({ element, appPlatform: AppDownloadPlatform.ANDROID, linkTarget: 'uniswap_wallet_playstore' }) } else { - openWalletMicrosite({ element }) + sendAnalyticsEvent(InterfaceEventName.UNISWAP_WALLET_MICROSITE_OPENED, { element }) + window.open(APP_DOWNLOAD_LINKS[element], /* target = */ 'uniswap_wallet_microsite') } } @@ -61,8 +62,3 @@ const openDownloadStore = (options: AnalyticsLinkOptions) => { }) window.open(APP_DOWNLOAD_LINKS[options.element], /* target = */ options.linkTarget) } - -export const openWalletMicrosite = (options: AnalyticsLinkOptions) => { - sendAnalyticsEvent(InterfaceEventName.UNISWAP_WALLET_MICROSITE_OPENED, { element: options.element }) - window.open(APP_DOWNLOAD_LINKS[options.element], /* target = */ 'uniswap_wallet_microsite') -}