-
Notifications
You must be signed in to change notification settings - Fork 5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
283 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,9 @@ | ||
import { swapsSlice } from '../swaps/swaps'; | ||
import { bridgeSlice } from './bridge'; | ||
|
||
// Bridge actions | ||
|
||
// eslint-disable-next-line no-empty-pattern | ||
const {} = swapsSlice.actions; | ||
// Proxied swaps actions | ||
export const { setFromToken, setToToken, setFromTokenInputValue } = | ||
swapsSlice.actions; | ||
|
||
// Bridge actions | ||
export const { setToChain } = bridgeSlice.actions; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
import React, { useState } from 'react'; | ||
import { | ||
Box, | ||
Button, | ||
Modal, | ||
ModalContent, | ||
ModalHeader, | ||
ModalOverlay, | ||
Text, | ||
TextFieldSearch, | ||
} from '../../../components/component-library'; | ||
import { useI18nContext } from '../../../hooks/useI18nContext'; | ||
import { useSelector } from 'react-redux'; | ||
import { | ||
BlockSize, | ||
Display, | ||
FlexDirection, | ||
TextAlign, | ||
TextVariant, | ||
} from '../../../helpers/constants/design-system'; | ||
import ItemList from '../../swaps/searchable-item-list/item-list/item-list.component'; | ||
import { getNonTestNetworks, getSwapsDefaultToken } from '../../../selectors'; | ||
import { isEqual } from 'lodash'; | ||
import { useTokensWithFiltering } from '../../../hooks/useTokensWithFiltering'; | ||
|
||
// TODO import from token-api | ||
// TODO write type validator for token | ||
type BridgeToken = {}; | ||
export const MultiChainTokenPicker = function <T = BridgeToken>({ | ||
selectedNetwork, | ||
selectedToken, | ||
networks, | ||
onTokenChange, | ||
onNetworkChange, | ||
}: { | ||
selectedToken: T; | ||
onTokenChange: (token: T) => void; | ||
networks: any[]; | ||
selectedNetwork?: any; | ||
onNetworkChange: (chainId: string, id?: string) => void; | ||
}) { | ||
const t = useI18nContext(); | ||
|
||
const [isOpen, setIsOpen] = useState(false); | ||
const [searchQuery, setSearchQuery] = useState(''); | ||
|
||
const defaultSwapsToken = useSelector(getSwapsDefaultToken, isEqual); | ||
|
||
// TODO use multichain token list - tokensChainsCache ? | ||
const filteredTokens = useTokensWithFiltering( | ||
// TODO handle dest chain native token - use generic default token selector instead? | ||
defaultSwapsToken, | ||
searchQuery, | ||
{}, | ||
() => { | ||
// TODO disable blocked tokens | ||
return false; | ||
}, | ||
selectedNetwork?.chainId, | ||
); | ||
|
||
// TODO does this work for networks the user hasn't added? | ||
const nonTestNetworks = useSelector(getNonTestNetworks); | ||
const onModalClose = () => { | ||
setSearchQuery(''); | ||
setIsOpen(false); | ||
}; | ||
|
||
return ( | ||
<Box className="multichain-asset-picker"> | ||
<div className="multichain-asset-picker__asset"> | ||
<Modal isOpen={isOpen} onClose={onModalClose}> | ||
<ModalOverlay /> | ||
<ModalContent modalDialogProps={{ padding: 0 }}> | ||
<ModalHeader onClose={onModalClose}> | ||
<Text | ||
variant={TextVariant.headingSm} | ||
textAlign={TextAlign.Center} | ||
> | ||
{t('bridge')} | ||
</Text> | ||
</ModalHeader> | ||
<Box className="network-list" width={BlockSize.Full} tabIndex="0"> | ||
<Box | ||
style={{ gridColumnStart: 1, gridColumnEnd: 3 }} | ||
display={Display.Flex} | ||
flexDirection={FlexDirection.Row} | ||
> | ||
{nonTestNetworks | ||
?.filter(({ chainId }) => networks.includes(chainId)) | ||
.map(({ chainId, id, nickname }) => ( | ||
<Button onClick={() => onNetworkChange(chainId, id)}> | ||
{nickname} | ||
</Button> | ||
))} | ||
</Box> | ||
</Box> | ||
<Box | ||
className="list-with-search" | ||
width={BlockSize.Full} | ||
tabIndex="0" | ||
> | ||
<Box | ||
style={{ gridColumnStart: 1, gridColumnEnd: 3 }} | ||
display={Display.Flex} | ||
flexDirection={FlexDirection.Column} | ||
> | ||
<TextFieldSearch | ||
id="multichain-asset-picker__asset-search" | ||
marginBottom={4} | ||
onChange={(e) => setSearchQuery(e.target.value)} | ||
clearButtonOnClick={() => setSearchQuery('')} | ||
value={searchQuery} | ||
placeholder={t('enterTokenNameOrAddress')} | ||
inputProps={{ marginRight: 0 }} | ||
className="list-with-search__text-search" | ||
autoFocus | ||
tabIndex="0" | ||
/> | ||
</Box> | ||
{filteredTokens?.length > 0 && ( | ||
<ItemList | ||
searchQuery={searchQuery} | ||
results={filteredTokens} | ||
onClickItem={(t) => { | ||
onTokenChange(t); | ||
setIsOpen(false); | ||
}} | ||
/> | ||
)} | ||
</Box> | ||
</ModalContent> | ||
</Modal> | ||
|
||
<Button onClick={() => setIsOpen(true)}> | ||
{selectedToken?.symbol ?? 'Select token'} | ||
</Button> | ||
</div> | ||
<div className="multichain-asset-picker__amount"></div> | ||
</Box> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,108 @@ | ||
import React from 'react'; | ||
import { useSelector, shallowEqual } from 'react-redux'; | ||
import { isEqual, shuffle } from 'lodash'; | ||
import PrepareSwapPage from '../../swaps/prepare-swap-page/prepare-swap-page'; | ||
import { getSelectedAccount, getTokenList } from '../../../selectors'; | ||
import { useSelector, useDispatch } from 'react-redux'; | ||
import { | ||
setFromToken, | ||
setFromTokenInputValue, | ||
setToChain, | ||
setToToken, | ||
} from '../../../ducks/bridge/actions'; | ||
import { | ||
getFromAmount, | ||
getFromChain, | ||
getFromChains, | ||
getFromToken, | ||
getToAmount, | ||
getToChain, | ||
getToChains, | ||
getToToken, | ||
} from '../../../ducks/bridge/selectors'; | ||
import { MultiChainTokenPicker } from '../components/multichain-token-picker'; | ||
import { Box, TextField } from '../../../components/component-library'; | ||
import { | ||
BlockSize, | ||
FlexDirection, | ||
} from '../../../helpers/constants/design-system'; | ||
import { setActiveNetwork } from '../../../store/actions'; | ||
|
||
export const PrepareBridgePage = () => { | ||
const selectedAccount = useSelector(getSelectedAccount, shallowEqual); | ||
const { balance: ethBalance, address: selectedAccountAddress } = | ||
selectedAccount; | ||
const PrepareBridgePage = () => { | ||
const dispatch = useDispatch(); | ||
|
||
const tokenList = useSelector(getTokenList, isEqual); | ||
const shuffledTokensList = shuffle(Object.values(tokenList)); | ||
const fromToken = useSelector(getFromToken); | ||
const toToken = useSelector(getToToken); | ||
|
||
const fromChains = useSelector(getFromChains); | ||
const toChains = useSelector(getToChains); | ||
const fromChain = useSelector(getFromChain); | ||
const toChain = useSelector(getToChain); | ||
|
||
const fromAmount = useSelector(getFromAmount); | ||
const toAmount = useSelector(getToAmount); | ||
|
||
// TODO copy in effects from PrepareSwapPage as needed | ||
// TODO implement new UI | ||
return ( | ||
<div> | ||
<PrepareSwapPage | ||
ethBalance={ethBalance} | ||
selectedAccountAddress={selectedAccountAddress} | ||
shuffledTokensList={shuffledTokensList} | ||
/> | ||
<div className="prepare-bridge-page"> | ||
<Box | ||
className="prepare-bridge-page__content" | ||
width={BlockSize.Full} | ||
flexDirection={FlexDirection.Column} | ||
> | ||
<Box | ||
className="from-input" | ||
width={BlockSize.Full} | ||
flexDirection={FlexDirection.Row} | ||
> | ||
{`BRIDGE FROM ${fromChain?.chainId}:${fromToken?.symbol} ${fromAmount}`} | ||
<MultiChainTokenPicker | ||
selectedNetwork={fromChain} | ||
selectedToken={fromToken} | ||
networks={fromChains} | ||
onTokenChange={(token) => dispatch(setFromToken(token))} | ||
onNetworkChange={(chainId, id) => { | ||
dispatch(setActiveNetwork(id)); | ||
// TODO emit metric | ||
// trackEvent({ | ||
// event: MetaMetricsEventName.NavNetworkSwitched, | ||
// category: MetaMetricsEventCategory.Network, | ||
// properties: { | ||
// location: 'Network Menu', | ||
// chain_id: currentChainId, | ||
// from_network: currentChainId, | ||
// to_network: network.chainId, | ||
// }, | ||
// }); | ||
// TODO refresh token list if it doesnt happen automatically | ||
}} | ||
/> | ||
<TextField | ||
value={fromAmount} | ||
onChange={(e) => { | ||
// TODO validate input | ||
dispatch(setFromTokenInputValue(e.target.value)); | ||
}} | ||
/> | ||
</Box> | ||
|
||
<Box | ||
className="to-input" | ||
width={BlockSize.Full} | ||
flexDirection={FlexDirection.Row} | ||
> | ||
{`BRIDGE TO ${toChain?.chainId}:${toToken?.symbol} ${toAmount}`} | ||
<MultiChainTokenPicker | ||
selectedNetwork={toChain} | ||
selectedToken={toToken} | ||
networks={toChains} | ||
onTokenChange={(token) => dispatch(setToToken(token))} | ||
onNetworkChange={(chainId, id) => { | ||
dispatch(setToChain(chainId)); | ||
console.log('TODO implement bridge action for this'); | ||
// TODO refresh token list if it doesnt happen automatically | ||
}} | ||
/> | ||
<TextField value={fromAmount} readOnly /> | ||
</Box> | ||
</Box> | ||
</div> | ||
); | ||
}; | ||
|
||
export default PrepareBridgePage; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters