diff --git a/src/assets/images/welcomeModal-dark.jpg b/src/assets/images/welcomeModal-dark.jpg new file mode 100644 index 0000000000..d7b8075713 Binary files /dev/null and b/src/assets/images/welcomeModal-dark.jpg differ diff --git a/src/assets/images/welcomeModal-dark@2x.jpg b/src/assets/images/welcomeModal-dark@2x.jpg new file mode 100644 index 0000000000..5043bb6712 Binary files /dev/null and b/src/assets/images/welcomeModal-dark@2x.jpg differ diff --git a/src/assets/images/welcomeModal-dark@3x.jpg b/src/assets/images/welcomeModal-dark@3x.jpg new file mode 100644 index 0000000000..1ce51e7849 Binary files /dev/null and b/src/assets/images/welcomeModal-dark@3x.jpg differ diff --git a/src/assets/images/welcomeModal-light.jpg b/src/assets/images/welcomeModal-light.jpg new file mode 100644 index 0000000000..849db5b349 Binary files /dev/null and b/src/assets/images/welcomeModal-light.jpg differ diff --git a/src/assets/images/welcomeModal-light@2x.jpg b/src/assets/images/welcomeModal-light@2x.jpg new file mode 100644 index 0000000000..b8ae653a1e Binary files /dev/null and b/src/assets/images/welcomeModal-light@2x.jpg differ diff --git a/src/assets/images/welcomeModal-light@3x.jpg b/src/assets/images/welcomeModal-light@3x.jpg new file mode 100644 index 0000000000..ea606182c5 Binary files /dev/null and b/src/assets/images/welcomeModal-light@3x.jpg differ diff --git a/src/components/Modal/index.tsx b/src/components/Modal/index.tsx index 90e7246806..22dd984710 100644 --- a/src/components/Modal/index.tsx +++ b/src/components/Modal/index.tsx @@ -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}; diff --git a/src/nft/components/explore/WelcomeModal.tsx b/src/nft/components/explore/WelcomeModal.tsx new file mode 100644 index 0000000000..abefeb7e55 --- /dev/null +++ b/src/nft/components/explore/WelcomeModal.tsx @@ -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 ( + + + + + Introducing Uniswap NFT + + We’re 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 you’ve 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.{' '} + + Learn more. + + + + + + + ) +} diff --git a/src/nft/pages/explore/index.tsx b/src/nft/pages/explore/index.tsx index cc5206fa06..254a91e7fa 100644 --- a/src/nft/pages/explore/index.tsx +++ b/src/nft/pages/explore/index.tsx @@ -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 = () => { + {!isModalHidden && } ) diff --git a/src/state/user/hooks.tsx b/src/state/user/hooks.tsx index 6eb5e2a011..caf9d50bc1 100644 --- a/src/state/user/hooks.tsx +++ b/src/state/user/hooks.tsx @@ -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() diff --git a/src/state/user/reducer.ts b/src/state/user/reducer.ts index 986eb0b9cf..d464acf2ec 100644 --- a/src/state/user/reducer.ts +++ b/src/state/user/reducer.ts @@ -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,