feat: create donation banner (#3403)
* create donation banner * update styling and copy * only show banner on swap page * dont use hard coded z index * style updates
This commit is contained in:
parent
b44eb8877c
commit
0a736b5e62
BIN
src/assets/images/ukraine.png
Normal file
BIN
src/assets/images/ukraine.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 121 KiB |
139
src/components/Popups/DonationLink.tsx
Normal file
139
src/components/Popups/DonationLink.tsx
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
import { Trans } from '@lingui/macro'
|
||||||
|
import FlagImage from 'assets/images/ukraine.png'
|
||||||
|
import { AutoColumn } from 'components/Column'
|
||||||
|
import { RowBetween, RowFixed } from 'components/Row'
|
||||||
|
import { X } from 'react-feather'
|
||||||
|
import ReactGA from 'react-ga'
|
||||||
|
import { useDarkModeManager, useShowDonationLink } from 'state/user/hooks'
|
||||||
|
import styled from 'styled-components/macro'
|
||||||
|
import { ExternalLink, ThemedText, Z_INDEX } from 'theme'
|
||||||
|
|
||||||
|
const darkGradient = `radial-gradient(87.53% 3032.45% at 5.16% 10.13%, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0) 100%),
|
||||||
|
linear-gradient(0deg, rgba(0, 91, 187, 0.35), rgba(0, 91, 187, 0.35)), #000000;`
|
||||||
|
const lightGradient = `radial-gradient(87.53% 3032.45% at 5.16% 10.13%, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0) 100%), linear-gradient(0deg, #CBE4FF, #CBE4FF), linear-gradient(0deg, rgba(255, 255, 255, 0.09), rgba(255, 255, 255, 0.09)), radial-gradient(100% 93.36% at 0% 6.64%, #8BC4FF 0%, #FFF5BF 100%);`
|
||||||
|
|
||||||
|
const Wrapper = styled(AutoColumn)<{ darkMode: boolean }>`
|
||||||
|
background: #edeef2;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 40px;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 18px;
|
||||||
|
max-width: 360px;
|
||||||
|
background: ${({ darkMode }) => (darkMode ? darkGradient : lightGradient)};
|
||||||
|
color: ${({ theme }) => theme.text1};
|
||||||
|
z-index: ${Z_INDEX.deprecated_content};
|
||||||
|
|
||||||
|
:hover {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > * {
|
||||||
|
z-index: ${Z_INDEX.fixed};
|
||||||
|
}
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
:before {
|
||||||
|
background-image: url(${FlagImage});
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
overflow: hidden;
|
||||||
|
background-size: 300px;
|
||||||
|
content: '';
|
||||||
|
height: 1200px;
|
||||||
|
width: 400px;
|
||||||
|
opacity: 0.1;
|
||||||
|
position: absolute;
|
||||||
|
transform: rotate(25deg) translate(-140px, -60px);
|
||||||
|
width: 300px;
|
||||||
|
z-index: ${Z_INDEX.deprecated_zero};
|
||||||
|
}
|
||||||
|
|
||||||
|
${({ theme }) => theme.mediaWidth.upToSmall`
|
||||||
|
max-width: 100%;
|
||||||
|
`}
|
||||||
|
|
||||||
|
${({ theme }) => theme.mediaWidth.upToMedium`
|
||||||
|
position: relative;
|
||||||
|
bottom: unset;
|
||||||
|
`}
|
||||||
|
`
|
||||||
|
|
||||||
|
const WrappedCloseIcon = styled(X)`
|
||||||
|
stroke: ${({ theme }) => theme.text2};
|
||||||
|
z-index: ${Z_INDEX.tooltip};
|
||||||
|
:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export const StyledFlagImage = styled.div`
|
||||||
|
margin-right: 12px;
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
border-radius: 100%;
|
||||||
|
&:before,
|
||||||
|
&:after {
|
||||||
|
content: '';
|
||||||
|
width: 9px;
|
||||||
|
height: 18px;
|
||||||
|
}
|
||||||
|
&:before {
|
||||||
|
float: left;
|
||||||
|
border-top-left-radius: 9px;
|
||||||
|
border-bottom-left-radius: 9px;
|
||||||
|
background: #005bbb;
|
||||||
|
}
|
||||||
|
&:after {
|
||||||
|
float: right;
|
||||||
|
border-top-right-radius: 9px;
|
||||||
|
border-bottom-right-radius: 9px;
|
||||||
|
background: #ffd500;
|
||||||
|
}
|
||||||
|
transform: rotate(90deg);
|
||||||
|
`
|
||||||
|
|
||||||
|
const StyledLink = styled(ExternalLink)`
|
||||||
|
text-decoration: none !important;
|
||||||
|
`
|
||||||
|
|
||||||
|
export default function DonationLink() {
|
||||||
|
const [darkMode] = useDarkModeManager()
|
||||||
|
const [, setVisible] = useShowDonationLink()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Wrapper
|
||||||
|
gap="10px"
|
||||||
|
darkMode={darkMode}
|
||||||
|
as={StyledLink}
|
||||||
|
target="https://donate.uniswap.org/#/swap"
|
||||||
|
href="https://donate.uniswap.org/#/swap"
|
||||||
|
onClickCapture={() => {
|
||||||
|
ReactGA.event({
|
||||||
|
category: 'Donate',
|
||||||
|
action: 'Link to Ukraine site.',
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<RowBetween>
|
||||||
|
<RowFixed>
|
||||||
|
<StyledFlagImage />
|
||||||
|
<ThemedText.Body fontWeight={600} fontSize={'18px'}>
|
||||||
|
<Trans>Donate to Ukraine</Trans>
|
||||||
|
</ThemedText.Body>
|
||||||
|
</RowFixed>
|
||||||
|
<WrappedCloseIcon
|
||||||
|
onClick={(e) => {
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
setVisible(false)
|
||||||
|
return false
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</RowBetween>
|
||||||
|
<ThemedText.Body fontWeight={400} fontSize="12px" color="text2">
|
||||||
|
<Trans>Directly support the Ukrainian government by donating tokens.</Trans>
|
||||||
|
</ThemedText.Body>
|
||||||
|
</Wrapper>
|
||||||
|
)
|
||||||
|
}
|
@ -1,12 +1,14 @@
|
|||||||
import { SupportedChainId } from 'constants/chains'
|
import { SupportedChainId } from 'constants/chains'
|
||||||
import useActiveWeb3React from 'hooks/useActiveWeb3React'
|
import useActiveWeb3React from 'hooks/useActiveWeb3React'
|
||||||
|
import { useLocation } from 'react-router-dom'
|
||||||
import styled from 'styled-components/macro'
|
import styled from 'styled-components/macro'
|
||||||
import { MEDIA_WIDTHS } from 'theme'
|
import { MEDIA_WIDTHS } from 'theme'
|
||||||
|
|
||||||
import { useActivePopups } from '../../state/application/hooks'
|
import { useActivePopups } from '../../state/application/hooks'
|
||||||
import { useURLWarningVisible } from '../../state/user/hooks'
|
import { useShowDonationLink, useURLWarningVisible } from '../../state/user/hooks'
|
||||||
import { AutoColumn } from '../Column'
|
import { AutoColumn } from '../Column'
|
||||||
import ClaimPopup from './ClaimPopup'
|
import ClaimPopup from './ClaimPopup'
|
||||||
|
import DonationLink from './DonationLink'
|
||||||
import PopupItem from './PopupItem'
|
import PopupItem from './PopupItem'
|
||||||
|
|
||||||
const MobilePopupWrapper = styled.div<{ height: string | number }>`
|
const MobilePopupWrapper = styled.div<{ height: string | number }>`
|
||||||
@ -14,11 +16,12 @@ const MobilePopupWrapper = styled.div<{ height: string | number }>`
|
|||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
height: ${({ height }) => height};
|
height: ${({ height }) => height};
|
||||||
margin: ${({ height }) => (height ? '0 auto;' : 0)};
|
margin: ${({ height }) => (height ? '0 auto;' : 0)};
|
||||||
margin-bottom: ${({ height }) => (height ? '20px' : 0)}};
|
margin-bottom: ${({ height }) => (height ? '20px' : 0)};
|
||||||
|
|
||||||
display: none;
|
display: none;
|
||||||
${({ theme }) => theme.mediaWidth.upToSmall`
|
${({ theme }) => theme.mediaWidth.upToSmall`
|
||||||
display: block;
|
display: block;
|
||||||
|
padding-top: 20px;
|
||||||
`};
|
`};
|
||||||
`
|
`
|
||||||
|
|
||||||
@ -65,6 +68,11 @@ export default function Popups() {
|
|||||||
const { chainId } = useActiveWeb3React()
|
const { chainId } = useActiveWeb3React()
|
||||||
const isNotOnMainnet = Boolean(chainId && chainId !== SupportedChainId.MAINNET)
|
const isNotOnMainnet = Boolean(chainId && chainId !== SupportedChainId.MAINNET)
|
||||||
|
|
||||||
|
const location = useLocation()
|
||||||
|
const isOnSwapPage = location.pathname.includes('swap')
|
||||||
|
const [donationVisible] = useShowDonationLink()
|
||||||
|
const showDonation = donationVisible && isOnSwapPage
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<FixedPopupColumn gap="20px" extraPadding={urlWarningActive} xlPadding={isNotOnMainnet}>
|
<FixedPopupColumn gap="20px" extraPadding={urlWarningActive} xlPadding={isNotOnMainnet}>
|
||||||
@ -72,9 +80,11 @@ export default function Popups() {
|
|||||||
{activePopups.map((item) => (
|
{activePopups.map((item) => (
|
||||||
<PopupItem key={item.key} content={item.content} popKey={item.key} removeAfterMs={item.removeAfterMs} />
|
<PopupItem key={item.key} content={item.content} popKey={item.key} removeAfterMs={item.removeAfterMs} />
|
||||||
))}
|
))}
|
||||||
|
{showDonation ? <DonationLink /> : null}
|
||||||
</FixedPopupColumn>
|
</FixedPopupColumn>
|
||||||
<MobilePopupWrapper height={activePopups?.length > 0 ? 'fit-content' : 0}>
|
<MobilePopupWrapper height={activePopups?.length > 0 || showDonation ? 'fit-content' : 0}>
|
||||||
<MobilePopupInner>
|
<MobilePopupInner>
|
||||||
|
{showDonation ? <DonationLink /> : null}
|
||||||
{activePopups // reverse so new items up front
|
{activePopups // reverse so new items up front
|
||||||
.slice(0)
|
.slice(0)
|
||||||
.reverse()
|
.reverse()
|
||||||
|
@ -19,6 +19,7 @@ export const updateUserDarkMode = createAction<{ userDarkMode: boolean }>('user/
|
|||||||
export const updateUserExpertMode = createAction<{ userExpertMode: boolean }>('user/updateUserExpertMode')
|
export const updateUserExpertMode = createAction<{ userExpertMode: boolean }>('user/updateUserExpertMode')
|
||||||
export const updateUserLocale = createAction<{ userLocale: SupportedLocale }>('user/updateUserLocale')
|
export const updateUserLocale = createAction<{ userLocale: SupportedLocale }>('user/updateUserLocale')
|
||||||
export const updateShowSurveyPopup = createAction<{ showSurveyPopup: boolean }>('user/updateShowSurveyPopup')
|
export const updateShowSurveyPopup = createAction<{ showSurveyPopup: boolean }>('user/updateShowSurveyPopup')
|
||||||
|
export const updateShowDonationLink = createAction<{ showDonationLink: boolean }>('user/updateShowDonationLink')
|
||||||
export const updateUserClientSideRouter = createAction<{ userClientSideRouter: boolean }>(
|
export const updateUserClientSideRouter = createAction<{ userClientSideRouter: boolean }>(
|
||||||
'user/updateUserClientSideRouter'
|
'user/updateUserClientSideRouter'
|
||||||
)
|
)
|
||||||
|
@ -4,6 +4,7 @@ import { L2_CHAIN_IDS } from 'constants/chains'
|
|||||||
import { SupportedLocale } from 'constants/locales'
|
import { SupportedLocale } from 'constants/locales'
|
||||||
import { L2_DEADLINE_FROM_NOW } from 'constants/misc'
|
import { L2_DEADLINE_FROM_NOW } from 'constants/misc'
|
||||||
import useActiveWeb3React from 'hooks/useActiveWeb3React'
|
import useActiveWeb3React from 'hooks/useActiveWeb3React'
|
||||||
|
import useCurrentBlockTimestamp from 'hooks/useCurrentBlockTimestamp'
|
||||||
import JSBI from 'jsbi'
|
import JSBI from 'jsbi'
|
||||||
import { useCallback, useMemo } from 'react'
|
import { useCallback, useMemo } from 'react'
|
||||||
import { shallowEqual } from 'react-redux'
|
import { shallowEqual } from 'react-redux'
|
||||||
@ -20,6 +21,7 @@ import {
|
|||||||
SerializedPair,
|
SerializedPair,
|
||||||
SerializedToken,
|
SerializedToken,
|
||||||
updateHideClosedPositions,
|
updateHideClosedPositions,
|
||||||
|
updateShowDonationLink,
|
||||||
updateShowSurveyPopup,
|
updateShowSurveyPopup,
|
||||||
updateUserClientSideRouter,
|
updateUserClientSideRouter,
|
||||||
updateUserDarkMode,
|
updateUserDarkMode,
|
||||||
@ -117,6 +119,26 @@ export function useShowSurveyPopup(): [boolean | undefined, (showPopup: boolean)
|
|||||||
return [showSurveyPopup, toggleShowSurveyPopup]
|
return [showSurveyPopup, toggleShowSurveyPopup]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DONATION_END_TIMESTAMP = 1646864954 // Jan 15th
|
||||||
|
|
||||||
|
export function useShowDonationLink(): [boolean | undefined, (showDonationLink: boolean) => void] {
|
||||||
|
const dispatch = useAppDispatch()
|
||||||
|
const showDonationLink = useAppSelector((state) => state.user.showDonationLink)
|
||||||
|
|
||||||
|
const toggleShowDonationLink = useCallback(
|
||||||
|
(showPopup: boolean) => {
|
||||||
|
dispatch(updateShowDonationLink({ showDonationLink: showPopup }))
|
||||||
|
},
|
||||||
|
[dispatch]
|
||||||
|
)
|
||||||
|
|
||||||
|
const timestamp = useCurrentBlockTimestamp()
|
||||||
|
const durationOver = timestamp ? timestamp.toNumber() > DONATION_END_TIMESTAMP : false
|
||||||
|
const donationVisible = showDonationLink !== false && !durationOver
|
||||||
|
|
||||||
|
return [donationVisible, toggleShowDonationLink]
|
||||||
|
}
|
||||||
|
|
||||||
export function useClientSideRouter(): [boolean, (userClientSideRouter: boolean) => void] {
|
export function useClientSideRouter(): [boolean, (userClientSideRouter: boolean) => void] {
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ import {
|
|||||||
SerializedToken,
|
SerializedToken,
|
||||||
updateHideClosedPositions,
|
updateHideClosedPositions,
|
||||||
updateMatchesDarkMode,
|
updateMatchesDarkMode,
|
||||||
|
updateShowDonationLink,
|
||||||
updateShowSurveyPopup,
|
updateShowSurveyPopup,
|
||||||
updateUserClientSideRouter,
|
updateUserClientSideRouter,
|
||||||
updateUserDarkMode,
|
updateUserDarkMode,
|
||||||
@ -64,6 +65,8 @@ export interface UserState {
|
|||||||
|
|
||||||
// undefined means has not gone through A/B split yet
|
// undefined means has not gone through A/B split yet
|
||||||
showSurveyPopup: boolean | undefined
|
showSurveyPopup: boolean | undefined
|
||||||
|
|
||||||
|
showDonationLink: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
function pairKey(token0Address: string, token1Address: string) {
|
function pairKey(token0Address: string, token1Address: string) {
|
||||||
@ -85,6 +88,7 @@ export const initialState: UserState = {
|
|||||||
timestamp: currentTimestamp(),
|
timestamp: currentTimestamp(),
|
||||||
URLWarningVisible: true,
|
URLWarningVisible: true,
|
||||||
showSurveyPopup: undefined,
|
showSurveyPopup: undefined,
|
||||||
|
showDonationLink: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default createReducer(initialState, (builder) =>
|
export default createReducer(initialState, (builder) =>
|
||||||
@ -155,6 +159,9 @@ export default createReducer(initialState, (builder) =>
|
|||||||
.addCase(updateShowSurveyPopup, (state, action) => {
|
.addCase(updateShowSurveyPopup, (state, action) => {
|
||||||
state.showSurveyPopup = action.payload.showSurveyPopup
|
state.showSurveyPopup = action.payload.showSurveyPopup
|
||||||
})
|
})
|
||||||
|
.addCase(updateShowDonationLink, (state, action) => {
|
||||||
|
state.showDonationLink = action.payload.showDonationLink
|
||||||
|
})
|
||||||
.addCase(addSerializedToken, (state, { payload: { serializedToken } }) => {
|
.addCase(addSerializedToken, (state, { payload: { serializedToken } }) => {
|
||||||
if (!state.tokens) {
|
if (!state.tokens) {
|
||||||
state.tokens = {}
|
state.tokens = {}
|
||||||
|
Loading…
Reference in New Issue
Block a user