fix(style): improve the bridge assets style (#3036)

* Re-style bridge cards

* Tweaks

- Header button height and color treatment refinement
- Small sizing issues

* Address comments

* remove network alert state

* code style nits

* remove unused parameter, rename

* copy edit

Co-authored-by: Moody Salem <moody.salem@gmail.com>
This commit is contained in:
Callil Capuozzo 2021-12-23 15:13:50 -05:00 committed by GitHub
parent 4ed9c7ba94
commit 3923438011
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 148 additions and 422 deletions

@ -23,7 +23,7 @@ export const BaseButton = styled(RebassButton)<
border-radius: ${({ $borderRadius }) => $borderRadius ?? '20px'}; border-radius: ${({ $borderRadius }) => $borderRadius ?? '20px'};
outline: none; outline: none;
border: 1px solid transparent; border: 1px solid transparent;
color: white; color: ${({ theme }) => theme.text1};
text-decoration: none; text-decoration: none;
display: flex; display: flex;
justify-content: center; justify-content: center;

@ -108,7 +108,7 @@ const SelectorControls = styled.div<{ interactive: boolean }>`
align-items: center; align-items: center;
background-color: ${({ theme }) => theme.bg0}; background-color: ${({ theme }) => theme.bg0};
border: 2px solid ${({ theme }) => theme.bg0}; border: 2px solid ${({ theme }) => theme.bg0};
border-radius: 12px; border-radius: 16px;
color: ${({ theme }) => theme.text1}; color: ${({ theme }) => theme.text1};
cursor: ${({ interactive }) => (interactive ? 'pointer' : 'auto')}; cursor: ${({ interactive }) => (interactive ? 'pointer' : 'auto')};
display: flex; display: flex;
@ -128,7 +128,7 @@ const SelectorWrapper = styled.div`
} }
` `
const StyledChevronDown = styled(ChevronDown)` const StyledChevronDown = styled(ChevronDown)`
width: 12px; width: 16px;
` `
const BridgeLabel = ({ chainId }: { chainId: SupportedChainId }) => { const BridgeLabel = ({ chainId }: { chainId: SupportedChainId }) => {
switch (chainId) { switch (chainId) {
@ -247,7 +247,7 @@ export default function NetworkSelector() {
<StyledChevronDown /> <StyledChevronDown />
</SelectorControls> </SelectorControls>
{open && ( {open && (
<FlyoutMenu> <FlyoutMenu onMouseLeave={toggle}>
<FlyoutHeader> <FlyoutHeader>
<Trans>Select a network</Trans> <Trans>Select a network</Trans>
</FlyoutHeader> </FlyoutHeader>

@ -89,7 +89,7 @@ const HeaderLinks = styled(Row)`
justify-self: center; justify-self: center;
background-color: ${({ theme }) => theme.bg0}; background-color: ${({ theme }) => theme.bg0};
width: fit-content; width: fit-content;
padding: 4px; padding: 2px;
border-radius: 16px; border-radius: 16px;
display: grid; display: grid;
grid-auto-flow: column; grid-auto-flow: column;
@ -121,10 +121,11 @@ const AccountElement = styled.div<{ active: boolean }>`
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
background-color: ${({ theme, active }) => (!active ? theme.bg1 : theme.bg1)}; background-color: ${({ theme, active }) => (!active ? theme.bg0 : theme.bg0)};
border-radius: 12px; border-radius: 16px;
white-space: nowrap; white-space: nowrap;
width: 100%; width: 100%;
height: 40px;
:focus { :focus {
border: 1px solid blue; border: 1px solid blue;
@ -202,11 +203,11 @@ const StyledNavLink = styled(NavLink).attrs({
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
&.${activeClassName} { &.${activeClassName} {
border-radius: 12px; border-radius: 14px;
font-weight: 600; font-weight: 600;
justify-content: center; justify-content: center;
color: ${({ theme }) => theme.text1}; color: ${({ theme }) => theme.text1};
background-color: ${({ theme }) => theme.bg2}; background-color: ${({ theme }) => theme.bg1};
} }
:hover, :hover,
@ -231,7 +232,7 @@ const StyledExternalLink = styled(ExternalLink).attrs({
font-weight: 500; font-weight: 500;
&.${activeClassName} { &.${activeClassName} {
border-radius: 12px; border-radius: 14px;
font-weight: 600; font-weight: 600;
color: ${({ theme }) => theme.text1}; color: ${({ theme }) => theme.text1};
} }

@ -49,12 +49,11 @@ const StyledMenuButton = styled.button`
background-color: transparent; background-color: transparent;
margin: 0; margin: 0;
padding: 0; padding: 0;
height: 38px; height: 40px;
background-color: ${({ theme }) => theme.bg0}; background-color: ${({ theme }) => theme.bg0};
border: 1px solid ${({ theme }) => theme.bg0}; border: 1px solid ${({ theme }) => theme.bg0};
padding: 0.15rem 0.5rem; padding: 0.15rem 0.5rem;
border-radius: 12px; border-radius: 16px;
:hover, :hover,
:focus { :focus {

@ -1,108 +1,77 @@
import { Trans } from '@lingui/macro' import { Trans } from '@lingui/macro'
import { SupportedChainId } from 'constants/chains' import { SupportedChainId } from 'constants/chains'
import { useActiveWeb3React } from 'hooks/web3' import { useActiveWeb3React } from 'hooks/web3'
import { useCallback, useMemo, useState } from 'react' import { ArrowUpRight } from 'react-feather'
import { ArrowDownCircle, X } from 'react-feather' import { useDarkModeManager } from 'state/user/hooks'
import { useDarkModeManager, useNetworkAlertStatus } from 'state/user/hooks'
import { useNativeCurrencyBalances } from 'state/wallet/hooks'
import styled from 'styled-components/macro' import styled from 'styled-components/macro'
import { ExternalLink, MEDIA_WIDTHS } from 'theme' import { ExternalLink, HideSmall } from 'theme'
import { CHAIN_INFO } from '../../constants/chains' import { CHAIN_INFO } from '../../constants/chains'
import { ThemedText } from '../../theme'
import { AutoRow } from '../Row' import { AutoRow } from '../Row'
const L2Icon = styled.img` const L2Icon = styled.img`
width: 36px; width: 24px;
height: 36px; height: 24px;
justify-self: center; margin-right: 16px;
margin-right: 14px;
`
const BetaTag = styled.span<{ color: string }>`
align-items: center;
background-color: ${({ color }) => color};
border-radius: 6px;
color: ${({ theme }) => theme.white};
display: flex;
font-size: 14px;
height: 28px;
justify-content: center;
left: -16px;
position: absolute;
transform: rotate(-15deg);
top: -16px;
width: 60px;
z-index: 1;
` `
export const Controls = styled.div` export const Controls = styled.div`
align-items: center; align-items: center;
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
padding: 0 20px 20px 20px; padding: 0 20px 20px 20px;
` `
const CloseIcon = styled(X)`
cursor: pointer;
position: absolute;
top: 16px;
right: 16px;
`
const BodyText = styled.div` const BodyText = styled.div`
align-items: center; color: ${({ color }) => color};
margin: 20px 16px;
@media screen and (min-width: ${MEDIA_WIDTHS.upToSmall}px) {
grid-template-columns: 42px 4fr;
grid-gap: 8px;
}
`
const LearnMoreLink = styled(ExternalLink)`
align-items: center;
background-color: transparent;
border: 1px solid rgba(255, 255, 255, 0.4);
border-radius: 8px;
color: ${({ theme }) => theme.text1};
display: flex; display: flex;
font-size: 16px; align-items: center;
height: 44px; justify-content: flex-start;
justify-content: space-between; margin: 8px;
padding: 12px 16px; font-size: 14px;
text-decoration: none;
width: auto;
:hover,
:focus,
:active {
background-color: rgba(255, 255, 255, 0.05);
}
transition: background-color 150ms ease-in-out;
` `
const RootWrapper = styled.div` const RootWrapper = styled.div`
position: relative; position: relative;
margin-top: 16px;
` `
const SHOULD_SHOW_ALERT = {
[SupportedChainId.OPTIMISM]: true,
[SupportedChainId.OPTIMISTIC_KOVAN]: true,
[SupportedChainId.ARBITRUM_ONE]: true,
[SupportedChainId.ARBITRUM_RINKEBY]: true,
[SupportedChainId.POLYGON]: true,
[SupportedChainId.POLYGON_MUMBAI]: true,
}
type NetworkAlertChains = keyof typeof SHOULD_SHOW_ALERT
const BG_COLORS_BY_DARK_MODE_AND_CHAIN_ID: { const BG_COLORS_BY_DARK_MODE_AND_CHAIN_ID: {
[darkMode in 'dark' | 'light']: { [chainId in SupportedChainId]?: string } [darkMode in 'dark' | 'light']: { [chainId in NetworkAlertChains]: string }
} = { } = {
dark: { dark: {
[SupportedChainId.POLYGON]: [SupportedChainId.POLYGON]:
'radial-gradient(100% 93.36% at 0% 6.64%, rgba(160, 108, 247, 0.3) 0%, rgba(82, 32, 166, 0.3) 100%)', 'radial-gradient(100% 93.36% at 0% 6.64%, rgba(160, 108, 247, 0.1) 0%, rgba(82, 32, 166, 0.1) 100%)',
[SupportedChainId.POLYGON_MUMBAI]: [SupportedChainId.POLYGON_MUMBAI]:
'radial-gradient(100% 93.36% at 0% 6.64%, rgba(160, 108, 247, 0.3) 0%, rgba(82, 32, 166, 0.3) 100%)', 'radial-gradient(100% 93.36% at 0% 6.64%, rgba(160, 108, 247, 0.1) 0%, rgba(82, 32, 166, 0.1) 100%)',
[SupportedChainId.OPTIMISM]: [SupportedChainId.OPTIMISM]:
'radial-gradient(948% 292% at 42% 0%, rgba(255, 58, 212, 0.2) 0%, rgba(255, 255, 255, 0.1) 100%),radial-gradient(98% 96% at 2% 0%, rgba(255, 39, 39, 0.5) 0%, rgba(235, 0, 255, 0.345) 96%)', 'radial-gradient(948% 292% at 42% 0%, rgba(255, 58, 212, 0.01) 0%, rgba(255, 255, 255, 0.04) 100%),radial-gradient(98% 96% at 2% 0%, rgba(255, 39, 39, 0.01) 0%, rgba(235, 0, 255, 0.01) 96%)',
[SupportedChainId.OPTIMISTIC_KOVAN]: [SupportedChainId.OPTIMISTIC_KOVAN]:
'radial-gradient(948% 292% at 42% 0%, rgba(255, 58, 212, 0.2) 0%, rgba(255, 255, 255, 0.1) 100%),radial-gradient(98% 96% at 2% 0%, rgba(255, 39, 39, 0.5) 0%, rgba(235, 0, 255, 0.345) 96%)', 'radial-gradient(948% 292% at 42% 0%, rgba(255, 58, 212, 0.04) 0%, rgba(255, 255, 255, 0.04) 100%),radial-gradient(98% 96% at 2% 0%, rgba(255, 39, 39, 0.04) 0%, rgba(235, 0, 255, 0.01 96%)',
[SupportedChainId.ARBITRUM_ONE]: [SupportedChainId.ARBITRUM_ONE]:
'radial-gradient(285% 8200% at 30% 50%, rgba(40, 160, 240, 0.1) 0%, rgba(219, 255, 0, 0) 100%),radial-gradient(75% 75% at 0% 0%, rgba(150, 190, 220, 0.3) 0%, rgba(33, 114, 229, 0.3) 100%), hsla(0, 0%, 100%, 0.1)', 'radial-gradient(285% 8200% at 30% 50%, rgba(40, 160, 240, 0.01) 0%, rgba(219, 255, 0, 0) 100%),radial-gradient(75% 75% at 0% 0%, rgba(150, 190, 220, 0.05) 0%, rgba(33, 114, 229, 0.05) 100%), hsla(0, 0%, 100%, 0.05)',
[SupportedChainId.ARBITRUM_RINKEBY]: [SupportedChainId.ARBITRUM_RINKEBY]:
'radial-gradient(285% 8200% at 30% 50%, rgba(40, 160, 240, 0.1) 0%, rgba(219, 255, 0, 0) 100%),radial-gradient(75% 75% at 0% 0%, rgba(150, 190, 220, 0.3) 0%, rgba(33, 114, 229, 0.3) 100%), hsla(0, 0%, 100%, 0.1)', 'radial-gradient(285% 8200% at 30% 50%, rgba(40, 160, 240, 0.05) 0%, rgba(219, 255, 0, 0) 100%),radial-gradient(75% 75% at 0% 0%, rgba(150, 190, 220, 0.05) 0%, rgba(33, 114, 229, 0.1) 100%), hsla(0, 0%, 100%, 0.05)',
}, },
light: { light: {
[SupportedChainId.POLYGON]: [SupportedChainId.POLYGON]:
'radial-gradient(182.71% 205.59% at 2.81% 7.69%, rgba(130, 71, 229, 0.3) 0%, rgba(167, 202, 255, 0.3) 100%)', 'radial-gradient(182.71% 205.59% at 2.81% 7.69%, rgba(130, 71, 229, 0.2) 0%, rgba(167, 202, 255, 0.2) 100%)',
[SupportedChainId.POLYGON_MUMBAI]: [SupportedChainId.POLYGON_MUMBAI]:
'radial-gradient(182.71% 205.59% at 2.81% 7.69%, rgba(130, 71, 229, 0.3) 0%, rgba(167, 202, 255, 0.3) 100%)', 'radial-gradient(182.71% 205.59% at 2.81% 7.69%, rgba(130, 71, 229, 0.2) 0%, rgba(167, 202, 255, 0.2) 100%)',
[SupportedChainId.OPTIMISM]: [SupportedChainId.OPTIMISM]:
'radial-gradient(92% 105% at 50% 7%, rgba(255, 58, 212, 0.04) 0%, rgba(255, 255, 255, 0.03) 100%),radial-gradient(100% 97% at 0% 12%, rgba(235, 0, 255, 0.1) 0%, rgba(243, 19, 19, 0.1) 100%), hsla(0, 0%, 100%, 0.5)', 'radial-gradient(92% 105% at 50% 7%, rgba(255, 58, 212, 0.04) 0%, rgba(255, 255, 255, 0.03) 100%),radial-gradient(100% 97% at 0% 12%, rgba(235, 0, 255, 0.1) 0%, rgba(243, 19, 19, 0.1) 100%), hsla(0, 0%, 100%, 0.1)',
[SupportedChainId.OPTIMISTIC_KOVAN]: [SupportedChainId.OPTIMISTIC_KOVAN]:
'radial-gradient(92% 105% at 50% 7%, rgba(255, 58, 212, 0.04) 0%, rgba(255, 255, 255, 0.03) 100%),radial-gradient(100% 97% at 0% 12%, rgba(235, 0, 255, 0.1) 0%, rgba(243, 19, 19, 0.1) 100%), hsla(0, 0%, 100%, 0.5)', 'radial-gradient(92% 105% at 50% 7%, rgba(255, 58, 212, 0.04) 0%, rgba(255, 255, 255, 0.03) 100%),radial-gradient(100% 97% at 0% 12%, rgba(235, 0, 255, 0.1) 0%, rgba(243, 19, 19, 0.1) 100%), hsla(0, 0%, 100%, 0.1)',
[SupportedChainId.ARBITRUM_ONE]: [SupportedChainId.ARBITRUM_ONE]:
'radial-gradient(285% 8200% at 30% 50%, rgba(40, 160, 240, 0.1) 0%, rgba(219, 255, 0, 0) 100%),radial-gradient(circle at top left, hsla(206, 50%, 75%, 0.01), hsla(215, 79%, 51%, 0.12)), hsla(0, 0%, 100%, 0.1)', 'radial-gradient(285% 8200% at 30% 50%, rgba(40, 160, 240, 0.1) 0%, rgba(219, 255, 0, 0) 100%),radial-gradient(circle at top left, hsla(206, 50%, 75%, 0.01), hsla(215, 79%, 51%, 0.12)), hsla(0, 0%, 100%, 0.1)',
[SupportedChainId.ARBITRUM_RINKEBY]: [SupportedChainId.ARBITRUM_RINKEBY]:
@ -110,14 +79,15 @@ const BG_COLORS_BY_DARK_MODE_AND_CHAIN_ID: {
}, },
} }
const ContentWrapper = styled.div<{ chainId: SupportedChainId; darkMode: boolean; logoUrl: string }>` const ContentWrapper = styled.div<{ chainId: NetworkAlertChains; darkMode: boolean; logoUrl: string }>`
background: ${({ chainId, darkMode }) => BG_COLORS_BY_DARK_MODE_AND_CHAIN_ID[darkMode ? 'dark' : 'light'][chainId]}; background: ${({ chainId, darkMode }) => BG_COLORS_BY_DARK_MODE_AND_CHAIN_ID[darkMode ? 'dark' : 'light'][chainId]};
border-radius: 20px; border-radius: 20px;
display: flex; display: flex;
flex-direction: column; flex-direction: row;
overflow: hidden; overflow: hidden;
position: relative; position: relative;
width: 100%; width: 100%;
:before { :before {
background-image: url(${({ logoUrl }) => logoUrl}); background-image: url(${({ logoUrl }) => logoUrl});
background-repeat: no-repeat; background-repeat: no-repeat;
@ -133,137 +103,43 @@ const ContentWrapper = styled.div<{ chainId: SupportedChainId; darkMode: boolean
` `
const Header = styled.h2` const Header = styled.h2`
font-weight: 600; font-weight: 600;
font-size: 20px; font-size: 16px;
margin: 0; margin: 0;
padding-right: 30px;
`
const LinkOutCircle = styled(ArrowDownCircle)`
margin-left: 12px;
transform: rotate(230deg);
width: 20px;
height: 20px;
` `
const LinkOutToBridge = styled(ExternalLink)` const LinkOutToBridge = styled(ExternalLink)`
align-items: center; align-items: center;
background-color: black;
border-radius: 8px; border-radius: 8px;
color: white; color: white;
display: flex; display: flex;
font-size: 16px; font-size: 16px;
height: 44px;
justify-content: space-between; justify-content: space-between;
padding: 12px 16px; padding: 6px 8px;
margin-right: 20px; margin-right: 12px;
text-decoration: none; text-decoration: none !important;
width: auto; width: 100%;
:hover,
:focus,
:active {
background-color: black;
}
` `
const DisclaimerText = styled(ThemedText.Body)` const StyledArrowUpRight = styled(ArrowUpRight)`
padding: 0 0.5em; margin-left: 12px;
font-size: 14px !important; width: 24px;
height: 24px;
` `
const BETA_TAG_COLORS: { [chainId in SupportedChainId]?: string } = { const TEXT_COLORS: { [chainId in NetworkAlertChains]: string } = {
[SupportedChainId.OPTIMISM]: '#ff0420', [SupportedChainId.POLYGON]: 'rgba(130, 71, 229)',
[SupportedChainId.OPTIMISTIC_KOVAN]: '#ff0420', [SupportedChainId.POLYGON_MUMBAI]: 'rgba(130, 71, 229)',
[SupportedChainId.OPTIMISM]: '#ff3856',
[SupportedChainId.OPTIMISTIC_KOVAN]: '#ff3856',
[SupportedChainId.ARBITRUM_ONE]: '#0490ed', [SupportedChainId.ARBITRUM_ONE]: '#0490ed',
[SupportedChainId.ARBITRUM_RINKEBY]: '#0490ed', [SupportedChainId.ARBITRUM_RINKEBY]: '#0490ed',
} }
const SHOULD_SHOW_ALERT: { [chainId in SupportedChainId]?: true } = { function shouldShowAlert(chainId: number | undefined): chainId is NetworkAlertChains {
[SupportedChainId.OPTIMISM]: true, return Boolean(chainId && SHOULD_SHOW_ALERT[chainId as unknown as NetworkAlertChains])
[SupportedChainId.OPTIMISTIC_KOVAN]: true,
[SupportedChainId.ARBITRUM_ONE]: true,
[SupportedChainId.ARBITRUM_RINKEBY]: true,
[SupportedChainId.POLYGON]: true,
[SupportedChainId.POLYGON_MUMBAI]: true,
}
function shouldShowAlert(chainId: number | undefined): chainId is SupportedChainId {
return Boolean(chainId && SHOULD_SHOW_ALERT[chainId as SupportedChainId])
} }
export function NetworkAlert() { export function NetworkAlert() {
const { account, chainId } = useActiveWeb3React()
const [darkMode] = useDarkModeManager()
const [alertAcknowledged, acknowledgeAlert] = useNetworkAlertStatus(chainId)
const [locallyDismissed, setLocallyDimissed] = useState(false)
const accounts = useMemo(() => (account ? [account] : []), [account])
const userNativeCurrencyBalance = useNativeCurrencyBalances(accounts)?.[account ?? '']
const dismiss = useCallback(() => {
setLocallyDimissed(true)
if (!alertAcknowledged) acknowledgeAlert()
}, [acknowledgeAlert, alertAcknowledged])
if (!shouldShowAlert(chainId) || alertAcknowledged || locallyDismissed) {
return null
}
const { label, logoUrl, bridge, helpCenterUrl } = CHAIN_INFO[chainId]
const showCloseIcon = Boolean(userNativeCurrencyBalance?.greaterThan(0))
const betaColor = BETA_TAG_COLORS[chainId]
return (
<RootWrapper>
{betaColor ? <BetaTag color={betaColor}>Beta</BetaTag> : null}
<ContentWrapper chainId={chainId} darkMode={darkMode} logoUrl={logoUrl}>
{showCloseIcon && <CloseIcon onClick={dismiss} />}
<BodyText>
<AutoRow style={{ marginBottom: '1em' }}>
<L2Icon src={logoUrl} />
<Header>
<Trans>Uniswap on {label}</Trans>
</Header>
</AutoRow>
<DisclaimerText>
{betaColor ? (
<Trans>
Please treat this as a beta release and learn about the risks before using {label}. To start trading on{' '}
{label}, first bridge your assets from L1 to L2.
</Trans>
) : (
<Trans>To start trading on {label}, first bridge your assets from L1 to L2.</Trans>
)}
</DisclaimerText>
</BodyText>
<Controls>
{bridge ? (
<LinkOutToBridge href={bridge}>
<Trans>Deposit Assets</Trans>
<LinkOutCircle />
</LinkOutToBridge>
) : null}
{helpCenterUrl ? (
<LearnMoreLink href={helpCenterUrl}>
<Trans>Learn More</Trans>
</LearnMoreLink>
) : null}
</Controls>
</ContentWrapper>
</RootWrapper>
)
}
const AlertRow = styled.div`
display: flex;
padding: 1em;
align-items: center;
`
const ButtonContainer = styled.div`
flex-shrink: 0;
flex-grow: 0;
display: flex;
height: 100%;
`
const FlexGrow = styled.div`
flex-grow: 1;
`
export function SingleRowNetworkAlert() {
const { chainId } = useActiveWeb3React() const { chainId } = useActiveWeb3React()
const [darkMode] = useDarkModeManager() const [darkMode] = useDarkModeManager()
@ -271,44 +147,27 @@ export function SingleRowNetworkAlert() {
return null return null
} }
const { label, logoUrl, bridge, helpCenterUrl } = CHAIN_INFO[chainId] const { label, logoUrl, bridge } = CHAIN_INFO[chainId]
const betaColor = BETA_TAG_COLORS[chainId] const textColor = TEXT_COLORS[chainId]
return ( return bridge ? (
<RootWrapper> <RootWrapper>
{betaColor ? <BetaTag color={betaColor}>Beta</BetaTag> : null}
<ContentWrapper chainId={chainId} darkMode={darkMode} logoUrl={logoUrl}> <ContentWrapper chainId={chainId} darkMode={darkMode} logoUrl={logoUrl}>
<AlertRow> <LinkOutToBridge href={bridge}>
<L2Icon src={logoUrl} /> <BodyText color={textColor}>
<L2Icon src={logoUrl} />
<FlexGrow> <AutoRow>
<DisclaimerText> <Header>
{betaColor ? ( <Trans>{label} token bridge</Trans>
<Trans> </Header>
Please treat this as a beta release and learn about the risks before using {label}. To start trading <HideSmall>
on {label}, first bridge your assets from L1 to L2. <Trans>Deposit tokens to the {label} network.</Trans>
</Trans> </HideSmall>
) : ( </AutoRow>
<Trans>To start trading on {label}, first bridge your assets from L1 to L2.</Trans> </BodyText>
)} <StyledArrowUpRight color={textColor} />
</DisclaimerText> </LinkOutToBridge>
</FlexGrow>
<ButtonContainer>
{bridge ? (
<LinkOutToBridge href={bridge}>
<Trans>Deposit Assets</Trans>
<LinkOutCircle />
</LinkOutToBridge>
) : null}
{helpCenterUrl ? (
<LearnMoreLink href={helpCenterUrl}>
<Trans>Learn More</Trans>
</LearnMoreLink>
) : null}
</ButtonContainer>
</AlertRow>
</ContentWrapper> </ContentWrapper>
</RootWrapper> </RootWrapper>
) ) : null
} }

@ -1,4 +1,5 @@
import { Trans } from '@lingui/macro' import { Trans } from '@lingui/macro'
import { ButtonText } from 'components/Button'
import PositionListItem from 'components/PositionListItem' import PositionListItem from 'components/PositionListItem'
import React from 'react' import React from 'react'
import styled from 'styled-components/macro' import styled from 'styled-components/macro'
@ -14,9 +15,7 @@ const DesktopHeader = styled.div`
@media screen and (min-width: ${MEDIA_WIDTHS.upToSmall}px) { @media screen and (min-width: ${MEDIA_WIDTHS.upToSmall}px) {
align-items: center; align-items: center;
display: flex; display: flex;
justify-content: space-between;
display: grid;
grid-template-columns: 1fr 1fr;
& > div:last-child { & > div:last-child {
text-align: right; text-align: right;
margin-right: 12px; margin-right: 12px;
@ -36,9 +35,15 @@ const MobileHeader = styled.div`
type PositionListProps = React.PropsWithChildren<{ type PositionListProps = React.PropsWithChildren<{
positions: PositionDetails[] positions: PositionDetails[]
setUserHideClosedPositions: any
userHideClosedPositions: boolean
}> }>
export default function PositionList({ positions }: PositionListProps) { export default function PositionList({
positions,
setUserHideClosedPositions,
userHideClosedPositions,
}: PositionListProps) {
return ( return (
<> <>
<DesktopHeader> <DesktopHeader>
@ -46,9 +51,9 @@ export default function PositionList({ positions }: PositionListProps) {
<Trans>Your positions</Trans> <Trans>Your positions</Trans>
{positions && ' (' + positions.length + ')'} {positions && ' (' + positions.length + ')'}
</div> </div>
<div> <ButtonText style={{ opacity: 0.6 }} onClick={() => setUserHideClosedPositions(!userHideClosedPositions)}>
<Trans>Status</Trans> <Trans>Hide closed positions</Trans>
</div> </ButtonText>
</DesktopHeader> </DesktopHeader>
<MobileHeader> <MobileHeader>
<Trans>Your positions</Trans> <Trans>Your positions</Trans>

@ -1,8 +1,6 @@
import { Trans } from '@lingui/macro'
import { Currency } from '@uniswap/sdk-core' import { Currency } from '@uniswap/sdk-core'
import { AutoColumn } from 'components/Column' import { AutoColumn } from 'components/Column'
import CurrencyLogo from 'components/CurrencyLogo' import CurrencyLogo from 'components/CurrencyLogo'
import QuestionHelper from 'components/QuestionHelper'
import { AutoRow } from 'components/Row' import { AutoRow } from 'components/Row'
import { COMMON_BASES } from 'constants/routing' import { COMMON_BASES } from 'constants/routing'
import { useTokenInfoFromActiveList } from 'hooks/useTokenInfoFromActiveList' import { useTokenInfoFromActiveList } from 'hooks/useTokenInfoFromActiveList'
@ -46,12 +44,6 @@ export default function CommonBases({
return bases.length > 0 ? ( return bases.length > 0 ? (
<MobileWrapper gap="md"> <MobileWrapper gap="md">
<AutoRow>
<Text fontWeight={500} fontSize={14}>
<Trans>Common bases</Trans>
</Text>
<QuestionHelper text={<Trans>These tokens are commonly paired with other tokens.</Trans>} />
</AutoRow>
<AutoRow gap="4px"> <AutoRow gap="4px">
{bases.map((currency: Currency) => { {bases.map((currency: Currency) => {
const isSelected = selectedCurrency?.equals(currency) const isSelected = selectedCurrency?.equals(currency)

@ -35,9 +35,12 @@ const Web3StatusGeneric = styled(ButtonSecondary)`
width: 100%; width: 100%;
align-items: center; align-items: center;
padding: 0.5rem; padding: 0.5rem;
border-radius: 12px; border-radius: 14px;
cursor: pointer; cursor: pointer;
user-select: none; user-select: none;
height: 36px;
margin-right: 2px;
margin-left: 1px;
:focus { :focus {
outline: none; outline: none;
} }
@ -82,7 +85,7 @@ const Web3StatusConnect = styled(Web3StatusGeneric)<{ faded?: boolean }>`
` `
const Web3StatusConnected = styled(Web3StatusGeneric)<{ pending?: boolean }>` const Web3StatusConnected = styled(Web3StatusGeneric)<{ pending?: boolean }>`
background-color: ${({ pending, theme }) => (pending ? theme.primary1 : theme.bg0)}; background-color: ${({ pending, theme }) => (pending ? theme.primary1 : theme.bg1)};
border: 1px solid ${({ pending, theme }) => (pending ? theme.primary1 : theme.bg1)}; border: 1px solid ${({ pending, theme }) => (pending ? theme.primary1 : theme.bg1)};
color: ${({ pending, theme }) => (pending ? theme.white : theme.text1)}; color: ${({ pending, theme }) => (pending ? theme.white : theme.text1)};
font-weight: 500; font-weight: 500;

@ -3,7 +3,6 @@ import { TransactionResponse } from '@ethersproject/providers'
import { Trans } from '@lingui/macro' import { Trans } from '@lingui/macro'
import { Currency, CurrencyAmount, Percent } from '@uniswap/sdk-core' import { Currency, CurrencyAmount, Percent } from '@uniswap/sdk-core'
import { FeeAmount, NonfungiblePositionManager } from '@uniswap/v3-sdk' import { FeeAmount, NonfungiblePositionManager } from '@uniswap/v3-sdk'
import DowntimeWarning from 'components/DowntimeWarning'
import UnsupportedCurrencyFooter from 'components/swap/UnsupportedCurrencyFooter' import UnsupportedCurrencyFooter from 'components/swap/UnsupportedCurrencyFooter'
import { useCallback, useContext, useEffect, useState } from 'react' import { useCallback, useContext, useEffect, useState } from 'react'
import { AlertTriangle } from 'react-feather' import { AlertTriangle } from 'react-feather'
@ -475,7 +474,6 @@ export default function AddLiquidity({
return ( return (
<> <>
<ScrollablePage> <ScrollablePage>
<DowntimeWarning />
<TransactionConfirmationModal <TransactionConfirmationModal
isOpen={showConfirm} isOpen={showConfirm}
onDismiss={handleDismissConfirmation} onDismiss={handleDismissConfirmation}

@ -5,14 +5,13 @@ import { useActiveWeb3React } from 'hooks/web3'
import styled from 'styled-components/macro' import styled from 'styled-components/macro'
import { ThemedText } from 'theme' import { ThemedText } from 'theme'
import Texture from '../../assets/images/sandtexture.webp'
import { ExternalLink } from '../../theme' import { ExternalLink } from '../../theme'
const CTASection = styled.section` const CTASection = styled.section`
display: grid; display: grid;
grid-template-columns: 2fr 1fr; grid-template-columns: 2fr 1.5fr;
gap: 8px; gap: 8px;
margin-top: 8px; opacity: 0.8;
${({ theme }) => theme.mediaWidth.upToSmall` ${({ theme }) => theme.mediaWidth.upToSmall`
grid-template-columns: auto; grid-template-columns: auto;
@ -21,22 +20,15 @@ const CTASection = styled.section`
` `
const CTA1 = styled(ExternalLink)` const CTA1 = styled(ExternalLink)`
background-color: ${({ theme }) => theme.bg2}; padding: 16px;
background: radial-gradient(
92.78% 103.09% at 50.06% 7.22%,
rgba(255, 58, 212, 0.072) 0%,
rgba(255, 255, 255, 0.042) 100%
),
radial-gradient(100% 97.16% at 0% 12.22%, rgba(235, 0, 255, 0.2) 0%, rgba(243, 19, 19, 0.2) 100%);
padding: 2rem;
border-radius: 20px; border-radius: 20px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
position: relative; position: relative;
justify-content: space-between; justify-content: center;
align-items: center; align-items: center;
overflow: hidden; overflow: hidden;
border: 1px solid transparent; border: 1px solid ${({ theme }) => theme.bg3};
* { * {
color: ${({ theme }) => theme.text1}; color: ${({ theme }) => theme.text1};
@ -44,36 +36,24 @@ const CTA1 = styled(ExternalLink)`
} }
:hover { :hover {
border: 1px solid ${({ theme }) => theme.bg0}; border: 1px solid ${({ theme }) => theme.bg4};
text-decoration: none; text-decoration: none;
* { * {
text-decoration: none !important; text-decoration: none !important;
} }
} }
:before {
content: '';
position: absolute;
width: 800%;
height: 480%;
top: -390px;
left: -310px;
z-index: -1;
opacity: 0.4;
background: url(${Texture}) 0 0 repeat;
transform: rotate(-4deg);
}
` `
const CTA2 = styled(ExternalLink)` const CTA2 = styled(ExternalLink)`
position: relative; position: relative;
overflow: hidden; overflow: hidden;
padding: 32px; padding: 16px;
border-radius: 20px; border-radius: 20px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: center;
border: 1px solid transparent; border: 1px solid ${({ theme }) => theme.bg3};
* { * {
color: ${({ theme }) => theme.text1}; color: ${({ theme }) => theme.text1};
@ -81,42 +61,30 @@ const CTA2 = styled(ExternalLink)`
} }
:hover { :hover {
border: 1px solid ${({ theme }) => theme.bg0}; border: 1px solid ${({ theme }) => theme.bg4};
text-decoration: none !important; text-decoration: none !important;
* { * {
text-decoration: none !important; text-decoration: none !important;
} }
} }
:before {
content: '';
position: absolute;
width: 340%;
height: 280%;
top: -170%;
left: -134%;
opacity: 0.4;
z-index: -1;
background: url(${Texture}) 0 0 repeat;
transform: rotate(-4deg);
}
` `
const HeaderText = styled(ThemedText.Label)` const HeaderText = styled(ThemedText.Label)`
align-items: center; align-items: center;
display: flex; display: flex;
margin-bottom: 24px;
font-weight: 400; font-weight: 400;
font-size: 20px; font-size: 16px;
${({ theme }) => theme.mediaWidth.upToMedium` ${({ theme }) => theme.mediaWidth.upToMedium`
font-size: 20px; font-size: 16px;
`}; `};
` `
const ResponsiveColumn = styled(AutoColumn)` const ResponsiveColumn = styled(AutoColumn)`
grid-template-columns: 1fr; grid-template-columns: 1fr;
width: 100%; width: 100%;
gap: 12px; gap: 8px;
${({ theme }) => theme.mediaWidth.upToMedium` ${({ theme }) => theme.mediaWidth.upToMedium`
gap: 8px; gap: 8px;
`}; `};
@ -133,7 +101,7 @@ export default function CTACards() {
<HeaderText> <HeaderText>
<Trans>Learn about providing liquidity</Trans> <Trans>Learn about providing liquidity</Trans>
</HeaderText> </HeaderText>
<ThemedText.Body fontWeight={300} style={{ alignItems: 'center', display: 'flex', maxWidth: '80%' }}> <ThemedText.Body fontWeight={400} style={{ alignItems: 'center', display: 'flex' }}>
<Trans>Check out our v3 LP walkthrough and migration guides.</Trans> <Trans>Check out our v3 LP walkthrough and migration guides.</Trans>
</ThemedText.Body> </ThemedText.Body>
</ResponsiveColumn> </ResponsiveColumn>
@ -143,8 +111,8 @@ export default function CTACards() {
<HeaderText style={{ alignSelf: 'flex-start' }}> <HeaderText style={{ alignSelf: 'flex-start' }}>
<Trans>Top pools</Trans> <Trans>Top pools</Trans>
</HeaderText> </HeaderText>
<ThemedText.Body fontWeight={300} style={{ alignSelf: 'flex-start' }}> <ThemedText.Body fontWeight={400} style={{ alignSelf: 'flex-start' }}>
<Trans>Explore popular pools on Uniswap Analytics.</Trans> <Trans>Explore Uniswap Analytics.</Trans>
</ThemedText.Body> </ThemedText.Body>
</ResponsiveColumn> </ResponsiveColumn>
</CTA2> </CTA2>

@ -1,10 +1,8 @@
import { Trans } from '@lingui/macro' import { Trans } from '@lingui/macro'
import { ButtonGray, ButtonOutlined, ButtonPrimary } from 'components/Button' import { ButtonGray, ButtonPrimary, ButtonText } from 'components/Button'
import { AutoColumn } from 'components/Column' import { AutoColumn } from 'components/Column'
import DowntimeWarning from 'components/DowntimeWarning'
import { FlyoutAlignment, NewMenu } from 'components/Menu' import { FlyoutAlignment, NewMenu } from 'components/Menu'
import { SwapPoolTabs } from 'components/NavigationTabs' import { SwapPoolTabs } from 'components/NavigationTabs'
import { SingleRowNetworkAlert } from 'components/NetworkAlert/NetworkAlert'
import PositionList from 'components/PositionList' import PositionList from 'components/PositionList'
import { RowBetween, RowFixed } from 'components/Row' import { RowBetween, RowFixed } from 'components/Row'
import { SwitchLocaleLink } from 'components/SwitchLocaleLink' import { SwitchLocaleLink } from 'components/SwitchLocaleLink'
@ -109,25 +107,6 @@ const MainContentWrapper = styled.main`
flex-direction: column; flex-direction: column;
` `
const ShowInactiveToggle = styled.div`
display: flex;
align-items: center;
justify-items: end;
grid-column-gap: 4px;
padding: 0 8px;
${({ theme }) => theme.mediaWidth.upToMedium`
margin-bottom: 12px;
`};
`
const ResponsiveRow = styled(RowFixed)`
justify-content: space-between;
width: 100%;
${({ theme }) => theme.mediaWidth.upToMedium`
flex-direction: column-reverse;
`};
`
function PositionsLoadingPlaceholder() { function PositionsLoadingPlaceholder() {
return ( return (
<LoadingRows> <LoadingRows>
@ -242,25 +221,31 @@ export default function Pool() {
</ButtonRow> </ButtonRow>
</TitleRow> </TitleRow>
<HideSmall>
<SingleRowNetworkAlert />
<DowntimeWarning />
<CTACards />
</HideSmall>
<MainContentWrapper> <MainContentWrapper>
{positionsLoading ? ( {positionsLoading ? (
<PositionsLoadingPlaceholder /> <PositionsLoadingPlaceholder />
) : filteredPositions && filteredPositions.length > 0 ? ( ) : filteredPositions && closedPositions && filteredPositions.length > 0 ? (
<PositionList positions={filteredPositions} /> <PositionList
positions={filteredPositions}
setUserHideClosedPositions={setUserHideClosedPositions}
userHideClosedPositions={userHideClosedPositions}
/>
) : ( ) : (
<NoLiquidity> <NoLiquidity>
<ThemedText.Body color={theme.text3} textAlign="center"> <ThemedText.Body color={theme.text3} textAlign="center">
<Inbox size={48} strokeWidth={1} style={{ marginBottom: '.5rem' }} /> <Inbox size={48} strokeWidth={1} style={{ marginBottom: '.5rem' }} />
<div> <div>
<Trans>Your V3 liquidity positions will appear here.</Trans> <Trans>Your active V3 liquidity positions will appear here.</Trans>
</div> </div>
</ThemedText.Body> </ThemedText.Body>
{!showConnectAWallet && closedPositions.length > 0 && (
<ButtonText
style={{ marginTop: '.5rem' }}
onClick={() => setUserHideClosedPositions(!userHideClosedPositions)}
>
<Trans>Show closed positions</Trans>
</ButtonText>
)}
{showConnectAWallet && ( {showConnectAWallet && (
<ButtonPrimary style={{ marginTop: '2em', padding: '8px 16px' }} onClick={toggleWalletModal}> <ButtonPrimary style={{ marginTop: '2em', padding: '8px 16px' }} onClick={toggleWalletModal}>
<Trans>Connect a wallet</Trans> <Trans>Connect a wallet</Trans>
@ -269,61 +254,9 @@ export default function Pool() {
</NoLiquidity> </NoLiquidity>
)} )}
</MainContentWrapper> </MainContentWrapper>
<HideSmall>
<ResponsiveRow> <CTACards />
{showV2Features && ( </HideSmall>
<RowFixed>
<ButtonOutlined
as={Link}
to="/pool/v2"
id="import-pool-link"
style={{
padding: '8px 16px',
margin: '0 4px',
borderRadius: '12px',
width: 'fit-content',
fontSize: '14px',
}}
>
<Layers size={14} style={{ marginRight: '8px' }} />
<Trans>View V2 Liquidity</Trans>
</ButtonOutlined>
{positions && positions.length > 0 && (
<ButtonOutlined
as={Link}
to="/migrate/v2"
id="import-pool-link"
style={{
padding: '8px 16px',
margin: '0 4px',
borderRadius: '12px',
width: 'fit-content',
fontSize: '14px',
}}
>
<ChevronsRight size={16} style={{ marginRight: '8px' }} />
<Trans>Migrate Liquidity</Trans>
</ButtonOutlined>
)}
</RowFixed>
)}
{closedPositions.length > 0 ? (
<ShowInactiveToggle>
<label>
<ThemedText.Body onClick={() => setUserHideClosedPositions(!userHideClosedPositions)}>
<Trans>Show closed positions</Trans>
</ThemedText.Body>
</label>
<input
type="checkbox"
onClick={() => setUserHideClosedPositions(!userHideClosedPositions)}
checked={!userHideClosedPositions}
/>
</ShowInactiveToggle>
) : null}
</ResponsiveRow>
</AutoColumn> </AutoColumn>
</AutoColumn> </AutoColumn>
</PageWrapper> </PageWrapper>

@ -56,7 +56,8 @@ import { warningSeverity } from '../../utils/prices'
import AppBody from '../AppBody' import AppBody from '../AppBody'
const AlertWrapper = styled.div` const AlertWrapper = styled.div`
max-width: 480px; max-width: 460px;
width: 100%;
` `
export default function Swap({ history }: RouteComponentProps) { export default function Swap({ history }: RouteComponentProps) {
@ -378,9 +379,6 @@ export default function Swap({ history }: RouteComponentProps) {
onConfirm={handleConfirmTokenWarning} onConfirm={handleConfirmTokenWarning}
onDismiss={handleDismissTokenWarning} onDismiss={handleDismissTokenWarning}
/> />
<AlertWrapper>
<NetworkAlert />
</AlertWrapper>
<AppBody> <AppBody>
<SwapHeader allowedSlippage={allowedSlippage} /> <SwapHeader allowedSlippage={allowedSlippage} />
<Wrapper id="swap-page"> <Wrapper id="swap-page">
@ -618,6 +616,9 @@ export default function Swap({ history }: RouteComponentProps) {
</AutoColumn> </AutoColumn>
</Wrapper> </Wrapper>
</AppBody> </AppBody>
<AlertWrapper>
<NetworkAlert />
</AlertWrapper>
<SwitchLocaleLink /> <SwitchLocaleLink />
{!swapIsUnsupported ? null : ( {!swapIsUnsupported ? null : (
<UnsupportedCurrencyFooter <UnsupportedCurrencyFooter

@ -16,7 +16,6 @@ export interface SerializedPair {
export const updateMatchesDarkMode = createAction<{ matchesDarkMode: boolean }>('user/updateMatchesDarkMode') export const updateMatchesDarkMode = createAction<{ matchesDarkMode: boolean }>('user/updateMatchesDarkMode')
export const updateUserDarkMode = createAction<{ userDarkMode: boolean }>('user/updateUserDarkMode') export const updateUserDarkMode = createAction<{ userDarkMode: boolean }>('user/updateUserDarkMode')
export const acknowledgeNetworkAlert = createAction<{ chainId: number }>('user/acknowledgeNetworkAlert')
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 updateUserClientSideRouter = createAction<{ userClientSideRouter: boolean }>( export const updateUserClientSideRouter = createAction<{ userClientSideRouter: boolean }>(

@ -14,7 +14,6 @@ import { useAllTokens } from '../../hooks/Tokens'
import { useActiveWeb3React } from '../../hooks/web3' import { useActiveWeb3React } from '../../hooks/web3'
import { AppState } from '../index' import { AppState } from '../index'
import { import {
acknowledgeNetworkAlert,
addSerializedPair, addSerializedPair,
addSerializedToken, addSerializedToken,
removeSerializedToken, removeSerializedToken,
@ -337,14 +336,3 @@ export function useTrackedTokenPairs(): [Token, Token][] {
return Object.keys(keyed).map((key) => keyed[key]) return Object.keys(keyed).map((key) => keyed[key])
}, [combinedList]) }, [combinedList])
} }
export function useNetworkAlertStatus(chainId: number | undefined): [boolean, () => void] {
const dispatch = useAppDispatch()
const alertAcknowledged = useAppSelector(({ user }) => user.networkAlertsAcknowledged)
const acknowledgeAlert = useCallback(() => {
if (typeof chainId !== 'number') return
dispatch(acknowledgeNetworkAlert({ chainId }))
}, [chainId, dispatch])
return [typeof chainId === 'number' ? alertAcknowledged[chainId] ?? false : false, acknowledgeAlert]
}

@ -1,11 +1,9 @@
import { createReducer } from '@reduxjs/toolkit' import { createReducer } from '@reduxjs/toolkit'
import { SupportedLocale } from 'constants/locales' import { SupportedLocale } from 'constants/locales'
import { SupportedChainId } from '../../constants/chains'
import { DEFAULT_DEADLINE_FROM_NOW } from '../../constants/misc' import { DEFAULT_DEADLINE_FROM_NOW } from '../../constants/misc'
import { updateVersion } from '../global/actions' import { updateVersion } from '../global/actions'
import { import {
acknowledgeNetworkAlert,
addSerializedPair, addSerializedPair,
addSerializedToken, addSerializedToken,
removeSerializedPair, removeSerializedPair,
@ -25,11 +23,6 @@ import {
const currentTimestamp = () => new Date().getTime() const currentTimestamp = () => new Date().getTime()
export interface UserState { export interface UserState {
// replaces the above two fields
networkAlertsAcknowledged: {
[chainId: number]: true
}
// the timestamp of the last updateVersion action // the timestamp of the last updateVersion action
lastUpdateVersionTimestamp?: number lastUpdateVersionTimestamp?: number
@ -75,7 +68,6 @@ function pairKey(token0Address: string, token1Address: string) {
export const initialState: UserState = { export const initialState: UserState = {
matchesDarkMode: false, matchesDarkMode: false,
networkAlertsAcknowledged: {},
userDarkMode: null, userDarkMode: null,
userExpertMode: false, userExpertMode: false,
userLocale: null, userLocale: null,
@ -123,20 +115,8 @@ export default createReducer(initialState, (builder) =>
state.userDeadline = DEFAULT_DEADLINE_FROM_NOW state.userDeadline = DEFAULT_DEADLINE_FROM_NOW
} }
state.networkAlertsAcknowledged = state.networkAlertsAcknowledged ?? {}
if ((state as unknown as { arbitrumAlphaAcknowledged: boolean }).arbitrumAlphaAcknowledged) {
state.networkAlertsAcknowledged[SupportedChainId.ARBITRUM_ONE] = true
}
if ((state as unknown as { optimismAlphaAcknowledged: boolean }).optimismAlphaAcknowledged) {
state.networkAlertsAcknowledged[SupportedChainId.OPTIMISM] = true
}
state.lastUpdateVersionTimestamp = currentTimestamp() state.lastUpdateVersionTimestamp = currentTimestamp()
}) })
.addCase(acknowledgeNetworkAlert, (state, action) => {
state.networkAlertsAcknowledged = state.networkAlertsAcknowledged ?? {}
state.networkAlertsAcknowledged[action.payload.chainId] = true
})
.addCase(updateUserDarkMode, (state, action) => { .addCase(updateUserDarkMode, (state, action) => {
state.userDarkMode = action.payload.userDarkMode state.userDarkMode = action.payload.userDarkMode
state.timestamp = currentTimestamp() state.timestamp = currentTimestamp()