feat: welcome nft banner (#5379)

* wip

* finished modal, waiting for assets

* feat: use srcset for better assets optimisation

* feat: bg photo

* various tweaks

* feat: wrap up logic

* chore: use proper link

* chore: bring switch back
This commit is contained in:
Mike Grabowski 2022-11-22 22:37:53 +01:00 committed by GitHub
parent d528b28203
commit 1a31560374
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 133 additions and 1 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 927 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 718 KiB

@ -8,7 +8,7 @@ import { Z_INDEX } from 'theme/zIndex'
import { isMobile } from '../../utils/userAgent'
const AnimatedDialogOverlay = animated(DialogOverlay)
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const StyledDialogOverlay = styled(AnimatedDialogOverlay)<{ scrollOverlay?: boolean }>`
&[data-reach-dialog-overlay] {
z-index: ${Z_INDEX.modalBackdrop};

@ -0,0 +1,111 @@
/* eslint-disable @typescript-eslint/no-var-requires */
import Modal from 'components/Modal'
import { useState } from 'react'
import { X } from 'react-feather'
import styled, { useTheme } from 'styled-components/macro'
import { ExternalLink } from 'theme/components'
import { ThemedText } from 'theme/components/text'
const Container = styled.div`
position: relative;
display: flex;
padding: 30% 24px 24px;
overflow: hidden;
height: fit-content;
user-select: none;
`
const CloseButton = styled(X)`
position: absolute;
top: 20px;
right: 24px;
cursor: pointer;
`
const Background = styled.img`
position: absolute;
top: 0;
left: 0;
width: 100%;
object-fit: contain;
`
const Content = styled.div`
display: flex;
flex-direction: column;
z-index: 1;
gap: 16px;
`
const Title = styled(ThemedText.LargeHeader)`
@media (max-width: ${({ theme }) => theme.breakpoint.xl}px) {
font-size: 20px !important;
}
`
const Paragraph = styled(ThemedText.BodySecondary)`
line-height: 24px;
@media (max-width: ${({ theme }) => theme.breakpoint.xl}px) {
font-size: 14px !important;
line-height: 20px;
}
`
const BACKGROUND_IMAGE = {
dark: {
src: require('../../../assets/images/welcomeModal-dark.jpg').default,
srcSet: `
${require('../../../assets/images/welcomeModal-dark@2x.jpg').default} 2x,
${require('../../../assets/images/welcomeModal-dark@3x.jpg').default} 3x,
`,
},
light: {
src: require('../../../assets/images/welcomeModal-light.jpg').default,
srcSet: `
${require('../../../assets/images/welcomeModal-light@2x.jpg').default} 2x,
${require('../../../assets/images/welcomeModal-light@3x.jpg').default} 3x,
`,
},
}
export function WelcomeModal({ onDismissed }: { onDismissed: () => void }) {
const [isOpen, setIsOpen] = useState(true)
const dismiss = () => {
setIsOpen(false)
setTimeout(() => onDismissed())
}
const theme = useTheme()
return (
<Modal isOpen={isOpen} onDismiss={dismiss} maxWidth={720}>
<Container>
<Background
{...(theme.darkMode ? BACKGROUND_IMAGE.dark : BACKGROUND_IMAGE.light)}
alt="Welcome modal background"
draggable={false}
/>
<Content>
<Title>Introducing Uniswap NFT</Title>
<Paragraph>
Were excited to announce that Uniswap Labs has acquired Genie to build the marketplace for all digital
assets! With Uniswap NFT, you can buy and sell NFTs across all marketplaces with the full functionality of
Genie. Additonally, if youve used Genie in the past, then you may be eligible for a USDC airdrop. You can
connect your wallet to claim any rewards. For more details on the airdrop please read the official
announcement on the Uniswap Labs blog.{' '}
<ExternalLink
href="https://uniswap.org/blog/uniswap-nft-aggregator-announcement"
title="Uniswap NFT aggregator announcement"
>
Learn more.
</ExternalLink>
</Paragraph>
<CloseButton size={24} onClick={dismiss} />
</Content>
</Container>
</Modal>
)
}

@ -2,8 +2,10 @@ import { Trace } from '@uniswap/analytics'
import { PageName } from '@uniswap/analytics-events'
import Banner from 'nft/components/explore/Banner'
import TrendingCollections from 'nft/components/explore/TrendingCollections'
import { WelcomeModal } from 'nft/components/explore/WelcomeModal'
import { useBag } from 'nft/hooks'
import { useEffect } from 'react'
import { useHideNFTWelcomeModal } from 'state/user/hooks'
import styled from 'styled-components/macro'
const ExploreContainer = styled.div`
@ -23,6 +25,7 @@ const ExploreContainer = styled.div`
const NftExplore = () => {
const setBagExpanded = useBag((state) => state.setBagExpanded)
const [isModalHidden, hideModal] = useHideNFTWelcomeModal()
useEffect(() => {
setBagExpanded({ bagExpanded: false, manualClose: false })
@ -35,6 +38,7 @@ const NftExplore = () => {
<Banner />
<TrendingCollections />
</ExploreContainer>
{!isModalHidden && <WelcomeModal onDismissed={hideModal} />}
</Trace>
</>
)

@ -19,6 +19,7 @@ import {
addSerializedToken,
removeSerializedToken,
updateHideClosedPositions,
updateHideNFTWelcomeModal,
updateShowNftPromoBanner,
updateShowSurveyPopup,
updateUserClientSideRouter,
@ -118,6 +119,15 @@ export function useShowSurveyPopup(): [boolean | undefined, (showPopup: boolean)
return [showSurveyPopup, toggleShowSurveyPopup]
}
export function useHideNFTWelcomeModal(): [boolean | undefined, () => void] {
const dispatch = useAppDispatch()
const hideNFTWelcomeModal = useAppSelector((state) => state.user.hideNFTWelcomeModal)
const hideModal = useCallback(() => {
dispatch(updateHideNFTWelcomeModal({ hideNFTWelcomeModal: true }))
}, [dispatch])
return [hideNFTWelcomeModal, hideModal]
}
export function useClientSideRouter(): [boolean, (userClientSideRouter: boolean) => void] {
const dispatch = useAppDispatch()

@ -54,6 +54,8 @@ export interface UserState {
showSurveyPopup: boolean | undefined
showDonationLink: boolean
hideNFTWelcomeModal: boolean
}
function pairKey(token0Address: string, token1Address: string) {
@ -78,6 +80,7 @@ export const initialState: UserState = {
hideNFTPromoBanner: false,
showSurveyPopup: undefined,
showDonationLink: true,
hideNFTWelcomeModal: true,
}
const userSlice = createSlice({
@ -123,6 +126,9 @@ const userSlice = createSlice({
updateShowDonationLink(state, action) {
state.showDonationLink = action.payload.showDonationLink
},
updateHideNFTWelcomeModal(state, action) {
state.hideNFTWelcomeModal = action.payload.hideNFTWelcomeModal
},
updateShowNftPromoBanner(state, action) {
state.hideNFTPromoBanner = action.payload.hideNFTPromoBanner
},
@ -210,6 +216,7 @@ export const {
updateShowDonationLink,
updateShowSurveyPopup,
updateUserClientSideRouter,
updateHideNFTWelcomeModal,
updateUserDarkMode,
updateUserDeadline,
updateUserExpertMode,