Commit 54531b53 authored by Justin Domingue's avatar Justin Domingue Committed by GitHub

refactor: migrate state/application to slice (#2615)

parent b286c1ba
...@@ -11,8 +11,8 @@ import { useOnClickOutside } from 'hooks/useOnClickOutside' ...@@ -11,8 +11,8 @@ import { useOnClickOutside } from 'hooks/useOnClickOutside'
import { useActiveWeb3React } from 'hooks/web3' import { useActiveWeb3React } from 'hooks/web3'
import { useCallback, useRef } from 'react' import { useCallback, useRef } from 'react'
import { ArrowDownCircle, ChevronDown } from 'react-feather' import { ArrowDownCircle, ChevronDown } from 'react-feather'
import { ApplicationModal } from 'state/application/actions'
import { useModalOpen, useToggleModal } from 'state/application/hooks' import { useModalOpen, useToggleModal } from 'state/application/hooks'
import { ApplicationModal } from 'state/application/reducer'
import { useAppSelector } from 'state/hooks' import { useAppSelector } from 'state/hooks'
import styled from 'styled-components/macro' import styled from 'styled-components/macro'
import { ExternalLink, MEDIA_WIDTHS } from 'theme' import { ExternalLink, MEDIA_WIDTHS } from 'theme'
......
...@@ -14,8 +14,8 @@ import styled, { css } from 'styled-components/macro' ...@@ -14,8 +14,8 @@ import styled, { css } from 'styled-components/macro'
import { ReactComponent as MenuIcon } from '../../assets/images/menu.svg' import { ReactComponent as MenuIcon } from '../../assets/images/menu.svg'
import { useOnClickOutside } from '../../hooks/useOnClickOutside' import { useOnClickOutside } from '../../hooks/useOnClickOutside'
import { useActiveWeb3React } from '../../hooks/web3' import { useActiveWeb3React } from '../../hooks/web3'
import { ApplicationModal } from '../../state/application/actions'
import { useModalOpen, useToggleModal } from '../../state/application/hooks' import { useModalOpen, useToggleModal } from '../../state/application/hooks'
import { ApplicationModal } from '../../state/application/reducer'
import { ExternalLink } from '../../theme' import { ExternalLink } from '../../theme'
import { ButtonPrimary } from '../Button' import { ButtonPrimary } from '../Button'
......
...@@ -8,13 +8,13 @@ import styled, { keyframes } from 'styled-components/macro' ...@@ -8,13 +8,13 @@ import styled, { keyframes } from 'styled-components/macro'
import tokenLogo from '../../assets/images/token-logo.png' import tokenLogo from '../../assets/images/token-logo.png'
import { ButtonPrimary } from '../../components/Button' import { ButtonPrimary } from '../../components/Button'
import { useActiveWeb3React } from '../../hooks/web3' import { useActiveWeb3React } from '../../hooks/web3'
import { ApplicationModal } from '../../state/application/actions'
import { import {
useModalOpen, useModalOpen,
useShowClaimPopup, useShowClaimPopup,
useToggleSelfClaimModal, useToggleSelfClaimModal,
useToggleShowClaimPopup, useToggleShowClaimPopup,
} from '../../state/application/hooks' } from '../../state/application/hooks'
import { ApplicationModal } from '../../state/application/reducer'
import { useUserHasAvailableClaim, useUserUnclaimedAmount } from '../../state/claim/hooks' import { useUserHasAvailableClaim, useUserUnclaimedAmount } from '../../state/claim/hooks'
import { TYPE } from '../../theme' import { TYPE } from '../../theme'
import { AutoColumn } from '../Column' import { AutoColumn } from '../Column'
......
...@@ -4,8 +4,8 @@ import { animated } from 'react-spring' ...@@ -4,8 +4,8 @@ import { animated } from 'react-spring'
import { useSpring } from 'react-spring/web' import { useSpring } from 'react-spring/web'
import styled, { ThemeContext } from 'styled-components/macro' import styled, { ThemeContext } from 'styled-components/macro'
import { PopupContent } from '../../state/application/actions'
import { useRemovePopup } from '../../state/application/hooks' import { useRemovePopup } from '../../state/application/hooks'
import { PopupContent } from '../../state/application/reducer'
import TransactionPopup from './TransactionPopup' import TransactionPopup from './TransactionPopup'
const StyledClose = styled(X)` const StyledClose = styled(X)`
......
...@@ -10,8 +10,8 @@ import { Text } from 'rebass' ...@@ -10,8 +10,8 @@ import { Text } from 'rebass'
import styled, { ThemeContext } from 'styled-components/macro' import styled, { ThemeContext } from 'styled-components/macro'
import { useOnClickOutside } from '../../hooks/useOnClickOutside' import { useOnClickOutside } from '../../hooks/useOnClickOutside'
import { ApplicationModal } from '../../state/application/actions'
import { useModalOpen, useToggleSettingsMenu } from '../../state/application/hooks' import { useModalOpen, useToggleSettingsMenu } from '../../state/application/hooks'
import { ApplicationModal } from '../../state/application/reducer'
import { useClientSideRouter, useExpertModeManager } from '../../state/user/hooks' import { useClientSideRouter, useExpertModeManager } from '../../state/user/hooks'
import { TYPE } from '../../theme' import { TYPE } from '../../theme'
import { ButtonError } from '../Button' import { ButtonError } from '../Button'
......
...@@ -4,6 +4,7 @@ import { UnsupportedChainIdError, useWeb3React } from '@web3-react/core' ...@@ -4,6 +4,7 @@ import { UnsupportedChainIdError, useWeb3React } from '@web3-react/core'
import { WalletConnectConnector } from '@web3-react/walletconnect-connector' import { WalletConnectConnector } from '@web3-react/walletconnect-connector'
import { AutoRow } from 'components/Row' import { AutoRow } from 'components/Row'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { ArrowLeft } from 'react-feather'
import ReactGA from 'react-ga' import ReactGA from 'react-ga'
import styled from 'styled-components/macro' import styled from 'styled-components/macro'
...@@ -13,8 +14,8 @@ import { fortmatic, injected, portis } from '../../connectors' ...@@ -13,8 +14,8 @@ import { fortmatic, injected, portis } from '../../connectors'
import { OVERLAY_READY } from '../../connectors/Fortmatic' import { OVERLAY_READY } from '../../connectors/Fortmatic'
import { SUPPORTED_WALLETS } from '../../constants/wallet' import { SUPPORTED_WALLETS } from '../../constants/wallet'
import usePrevious from '../../hooks/usePrevious' import usePrevious from '../../hooks/usePrevious'
import { ApplicationModal } from '../../state/application/actions'
import { useModalOpen, useWalletModalToggle } from '../../state/application/hooks' import { useModalOpen, useWalletModalToggle } from '../../state/application/hooks'
import { ApplicationModal } from '../../state/application/reducer'
import { ExternalLink, TYPE } from '../../theme' import { ExternalLink, TYPE } from '../../theme'
import { isMobile } from '../../utils/userAgent' import { isMobile } from '../../utils/userAgent'
import AccountDetails from '../AccountDetails' import AccountDetails from '../AccountDetails'
...@@ -330,7 +331,7 @@ export default function WalletModal({ ...@@ -330,7 +331,7 @@ export default function WalletModal({
setWalletView(WALLET_VIEWS.ACCOUNT) setWalletView(WALLET_VIEWS.ACCOUNT)
}} }}
> >
<Trans>Back</Trans> <ArrowLeft />
</HoverText> </HoverText>
</HeaderRow> </HeaderRow>
) : ( ) : (
...@@ -344,14 +345,14 @@ export default function WalletModal({ ...@@ -344,14 +345,14 @@ export default function WalletModal({
<ContentWrapper> <ContentWrapper>
<LightCard style={{ marginBottom: '16px' }}> <LightCard style={{ marginBottom: '16px' }}>
<AutoRow style={{ flexWrap: 'nowrap' }}> <AutoRow style={{ flexWrap: 'nowrap' }}>
<TYPE.main fontSize={14}> <TYPE.black fontSize={14}>
<Trans> <Trans>
By connecting a wallet, you agree to Uniswap Labs’{' '} By connecting a wallet, you agree to Uniswap Labs’{' '}
<ExternalLink href="https://uniswap.org/terms-of-service/">Terms of Service</ExternalLink> and <ExternalLink href="https://uniswap.org/terms-of-service/">Terms of Service</ExternalLink> and
acknowledge that you have read and understand the{' '} acknowledge that you have read and understand the{' '}
<ExternalLink href="https://uniswap.org/disclaimer/">Uniswap protocol disclaimer</ExternalLink>. <ExternalLink href="https://uniswap.org/disclaimer/">Uniswap protocol disclaimer</ExternalLink>.
</Trans> </Trans>
</TYPE.main> </TYPE.black>
</AutoRow> </AutoRow>
</LightCard> </LightCard>
{walletView === WALLET_VIEWS.PENDING ? ( {walletView === WALLET_VIEWS.PENDING ? (
......
...@@ -9,8 +9,8 @@ import styled from 'styled-components/macro' ...@@ -9,8 +9,8 @@ import styled from 'styled-components/macro'
import Circle from '../../assets/images/blue-loader.svg' import Circle from '../../assets/images/blue-loader.svg'
import tokenLogo from '../../assets/images/token-logo.png' import tokenLogo from '../../assets/images/token-logo.png'
import { useActiveWeb3React } from '../../hooks/web3' import { useActiveWeb3React } from '../../hooks/web3'
import { ApplicationModal } from '../../state/application/actions'
import { useModalOpen, useToggleSelfClaimModal } from '../../state/application/hooks' import { useModalOpen, useToggleSelfClaimModal } from '../../state/application/hooks'
import { ApplicationModal } from '../../state/application/reducer'
import { useClaimCallback, useUserClaimData, useUserUnclaimedAmount } from '../../state/claim/hooks' import { useClaimCallback, useUserClaimData, useUserUnclaimedAmount } from '../../state/claim/hooks'
import { useUserHasSubmittedClaim } from '../../state/transactions/hooks' import { useUserHasSubmittedClaim } from '../../state/transactions/hooks'
import { CloseIcon, CustomLightSpinner, ExternalLink, TYPE, UniTokenAnimated } from '../../theme' import { CloseIcon, CustomLightSpinner, ExternalLink, TYPE, UniTokenAnimated } from '../../theme'
......
...@@ -9,8 +9,8 @@ import Header from '../components/Header' ...@@ -9,8 +9,8 @@ import Header from '../components/Header'
import Polling from '../components/Header/Polling' import Polling from '../components/Header/Polling'
import Popups from '../components/Popups' import Popups from '../components/Popups'
import Web3ReactManager from '../components/Web3ReactManager' import Web3ReactManager from '../components/Web3ReactManager'
import { ApplicationModal } from '../state/application/actions'
import { useModalOpen, useToggleModal } from '../state/application/hooks' import { useModalOpen, useToggleModal } from '../state/application/hooks'
import { ApplicationModal } from '../state/application/reducer'
import DarkModeQueryParamReader from '../theme/DarkModeQueryParamReader' import DarkModeQueryParamReader from '../theme/DarkModeQueryParamReader'
import AddLiquidity from './AddLiquidity' import AddLiquidity from './AddLiquidity'
import { RedirectDuplicateTokenIds } from './AddLiquidity/redirects' import { RedirectDuplicateTokenIds } from './AddLiquidity/redirects'
......
...@@ -2,7 +2,7 @@ import { useEffect } from 'react' ...@@ -2,7 +2,7 @@ import { useEffect } from 'react'
import { Redirect, RouteComponentProps } from 'react-router-dom' import { Redirect, RouteComponentProps } from 'react-router-dom'
import { useAppDispatch } from 'state/hooks' import { useAppDispatch } from 'state/hooks'
import { ApplicationModal, setOpenModal } from '../../state/application/actions' import { ApplicationModal, setOpenModal } from '../../state/application/reducer'
// Redirects to swap but only replace the pathname // Redirects to swap but only replace the pathname
export function RedirectPathToSwapOnly({ location }: RouteComponentProps) { export function RedirectPathToSwapOnly({ location }: RouteComponentProps) {
......
...@@ -27,8 +27,8 @@ import { ...@@ -27,8 +27,8 @@ import {
import { ZERO_ADDRESS } from '../../constants/misc' import { ZERO_ADDRESS } from '../../constants/misc'
import { UNI } from '../../constants/tokens' import { UNI } from '../../constants/tokens'
import { useActiveWeb3React } from '../../hooks/web3' import { useActiveWeb3React } from '../../hooks/web3'
import { ApplicationModal } from '../../state/application/actions'
import { useBlockNumber, useModalOpen, useToggleDelegateModal, useToggleVoteModal } from '../../state/application/hooks' import { useBlockNumber, useModalOpen, useToggleDelegateModal, useToggleVoteModal } from '../../state/application/hooks'
import { ApplicationModal } from '../../state/application/reducer'
import { import {
ProposalData, ProposalData,
ProposalState, ProposalState,
......
...@@ -14,8 +14,8 @@ import JSBI from 'jsbi' ...@@ -14,8 +14,8 @@ import JSBI from 'jsbi'
import { darken } from 'polished' import { darken } from 'polished'
import { Link } from 'react-router-dom' import { Link } from 'react-router-dom'
import { Button } from 'rebass/styled-components' import { Button } from 'rebass/styled-components'
import { ApplicationModal } from 'state/application/actions'
import { useModalOpen, useToggleDelegateModal } from 'state/application/hooks' import { useModalOpen, useToggleDelegateModal } from 'state/application/hooks'
import { ApplicationModal } from 'state/application/reducer'
import { ProposalData, useAllProposalData, useUserDelegatee, useUserVotes } from 'state/governance/hooks' import { ProposalData, useAllProposalData, useUserDelegatee, useUserVotes } from 'state/governance/hooks'
import { useTokenBalance } from 'state/wallet/hooks' import { useTokenBalance } from 'state/wallet/hooks'
import styled from 'styled-components/macro' import styled from 'styled-components/macro'
......
import { createAction } from '@reduxjs/toolkit'
export type PopupContent = {
txn: {
hash: string
}
}
export enum ApplicationModal {
WALLET,
SETTINGS,
SELF_CLAIM,
ADDRESS_CLAIM,
CLAIM_POPUP,
MENU,
DELEGATE,
VOTE,
POOL_OVERVIEW_OPTIONS,
NETWORK_SELECTOR,
}
export const updateChainId = createAction<{ chainId: number | null }>('application/updateChainId')
export const updateBlockNumber = createAction<{ chainId: number; blockNumber: number }>('application/updateBlockNumber')
export const setOpenModal = createAction<ApplicationModal | null>('application/setOpenModal')
export const addPopup =
createAction<{ key?: string; removeAfterMs?: number | null; content: PopupContent }>('application/addPopup')
export const removePopup = createAction<{ key: string }>('application/removePopup')
export const setImplements3085 = createAction<{ implements3085: boolean }>('application/setImplements3085')
export const setChainConnectivityWarning = createAction<{ warn: boolean }>('application/setChainConnectivityWarning')
...@@ -4,7 +4,7 @@ import { useAppDispatch, useAppSelector } from 'state/hooks' ...@@ -4,7 +4,7 @@ import { useAppDispatch, useAppSelector } from 'state/hooks'
import { useActiveWeb3React } from '../../hooks/web3' import { useActiveWeb3React } from '../../hooks/web3'
import { AppState } from '../index' import { AppState } from '../index'
import { addPopup, ApplicationModal, PopupContent, removePopup, setOpenModal } from './actions' import { addPopup, ApplicationModal, PopupContent, removePopup, setOpenModal } from './reducer'
export function useBlockNumber(): number | undefined { export function useBlockNumber(): number | undefined {
const { chainId } = useActiveWeb3React() const { chainId } = useActiveWeb3React()
......
import { createStore, Store } from 'redux' import { createStore, Store } from 'redux'
import { addPopup, ApplicationModal, removePopup, setOpenModal, updateBlockNumber, updateChainId } from './actions' import reducer, {
import reducer, { ApplicationState } from './reducer' addPopup,
ApplicationModal,
ApplicationState,
removePopup,
setOpenModal,
updateBlockNumber,
updateChainId,
} from './reducer'
describe('application reducer', () => { describe('application reducer', () => {
let store: Store<ApplicationState> let store: Store<ApplicationState>
beforeEach(() => { beforeEach(() => {
store = createStore(reducer, { store = createStore(reducer, {
chainId: null,
chainConnectivityWarning: false,
popupList: [],
blockNumber: { blockNumber: {
[1]: 3, [1]: 3,
}, },
chainId: null,
chainConnectivityWarning: false,
implements3085: false,
openModal: null, openModal: null,
popupList: [],
}) })
}) })
......
import { createReducer, nanoid } from '@reduxjs/toolkit' import { createSlice, nanoid } from '@reduxjs/toolkit'
import { DEFAULT_TXN_DISMISS_MS } from 'constants/misc' import { DEFAULT_TXN_DISMISS_MS } from 'constants/misc'
import { export type PopupContent = {
addPopup, txn: {
ApplicationModal, hash: string
PopupContent, }
removePopup, }
setChainConnectivityWarning,
setImplements3085, export enum ApplicationModal {
setOpenModal, WALLET,
updateBlockNumber, SETTINGS,
updateChainId, SELF_CLAIM,
} from './actions' ADDRESS_CLAIM,
CLAIM_POPUP,
MENU,
DELEGATE,
VOTE,
POOL_OVERVIEW_OPTIONS,
NETWORK_SELECTOR,
}
type PopupList = Array<{ key: string; show: boolean; content: PopupContent; removeAfterMs: number | null }> type PopupList = Array<{ key: string; show: boolean; content: PopupContent; removeAfterMs: number | null }>
...@@ -33,24 +40,26 @@ const initialState: ApplicationState = { ...@@ -33,24 +40,26 @@ const initialState: ApplicationState = {
popupList: [], popupList: [],
} }
export default createReducer(initialState, (builder) => const applicationSlice = createSlice({
builder name: 'application',
.addCase(updateChainId, (state, action) => { initialState,
reducers: {
updateChainId(state, action) {
const { chainId } = action.payload const { chainId } = action.payload
state.chainId = chainId state.chainId = chainId
}) },
.addCase(updateBlockNumber, (state, action) => { updateBlockNumber(state, action) {
const { chainId, blockNumber } = action.payload const { chainId, blockNumber } = action.payload
if (typeof state.blockNumber[chainId] !== 'number') { if (typeof state.blockNumber[chainId] !== 'number') {
state.blockNumber[chainId] = blockNumber state.blockNumber[chainId] = blockNumber
} else { } else {
state.blockNumber[chainId] = Math.max(blockNumber, state.blockNumber[chainId]) state.blockNumber[chainId] = Math.max(blockNumber, state.blockNumber[chainId])
} }
}) },
.addCase(setOpenModal, (state, action) => { setOpenModal(state, action) {
state.openModal = action.payload state.openModal = action.payload
}) },
.addCase(addPopup, (state, { payload: { content, key, removeAfterMs = DEFAULT_TXN_DISMISS_MS } }) => { addPopup(state, { payload: { content, key, removeAfterMs = DEFAULT_TXN_DISMISS_MS } }) {
state.popupList = (key ? state.popupList.filter((popup) => popup.key !== key) : state.popupList).concat([ state.popupList = (key ? state.popupList.filter((popup) => popup.key !== key) : state.popupList).concat([
{ {
key: key || nanoid(), key: key || nanoid(),
...@@ -59,18 +68,30 @@ export default createReducer(initialState, (builder) => ...@@ -59,18 +68,30 @@ export default createReducer(initialState, (builder) =>
removeAfterMs, removeAfterMs,
}, },
]) ])
}) },
.addCase(removePopup, (state, { payload: { key } }) => { removePopup(state, { payload: { key } }) {
state.popupList.forEach((p) => { state.popupList.forEach((p) => {
if (p.key === key) { if (p.key === key) {
p.show = false p.show = false
} }
}) })
}) },
.addCase(setImplements3085, (state, { payload: { implements3085 } }) => { setImplements3085(state, { payload: { implements3085 } }) {
state.implements3085 = implements3085 state.implements3085 = implements3085
}) },
.addCase(setChainConnectivityWarning, (state, { payload: { warn } }) => { setChainConnectivityWarning(state, { payload: { warn } }) {
state.chainConnectivityWarning = warn state.chainConnectivityWarning = warn
}) },
) },
})
export const {
updateChainId,
updateBlockNumber,
setOpenModal,
addPopup,
removePopup,
setImplements3085,
setChainConnectivityWarning,
} = applicationSlice.actions
export default applicationSlice.reducer
...@@ -9,8 +9,8 @@ import { useAppDispatch, useAppSelector } from 'state/hooks' ...@@ -9,8 +9,8 @@ import { useAppDispatch, useAppSelector } from 'state/hooks'
import { supportedChainId } from 'utils/supportedChainId' import { supportedChainId } from 'utils/supportedChainId'
import { switchToNetwork } from 'utils/switchToNetwork' import { switchToNetwork } from 'utils/switchToNetwork'
import { setChainConnectivityWarning, setImplements3085, updateBlockNumber, updateChainId } from './actions'
import { useBlockNumber } from './hooks' import { useBlockNumber } from './hooks'
import { setChainConnectivityWarning, setImplements3085, updateBlockNumber, updateChainId } from './reducer'
function useQueryCacheInvalidator() { function useQueryCacheInvalidator() {
const dispatch = useAppDispatch() const dispatch = useAppDispatch()
......
...@@ -5,8 +5,8 @@ import { useAppDispatch, useAppSelector } from 'state/hooks' ...@@ -5,8 +5,8 @@ import { useAppDispatch, useAppSelector } from 'state/hooks'
import { L2_CHAIN_IDS, SupportedChainId } from '../../constants/chains' import { L2_CHAIN_IDS, SupportedChainId } from '../../constants/chains'
import { useActiveWeb3React } from '../../hooks/web3' import { useActiveWeb3React } from '../../hooks/web3'
import { retry, RetryableError, RetryOptions } from '../../utils/retry' import { retry, RetryableError, RetryOptions } from '../../utils/retry'
import { updateBlockNumber } from '../application/actions'
import { useAddPopup, useBlockNumber } from '../application/hooks' import { useAddPopup, useBlockNumber } from '../application/hooks'
import { updateBlockNumber } from '../application/reducer'
import { checkedTransaction, finalizeTransaction } from './actions' import { checkedTransaction, finalizeTransaction } from './actions'
interface TxInterface { interface TxInterface {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment