Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
I
interface
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
LuckySwap
interface
Commits
94dc3898
Unverified
Commit
94dc3898
authored
Sep 07, 2022
by
cartcrom
Committed by
GitHub
Sep 07, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: widget speedbumps on swap review (#4544)
* initial commit * finished feature * addressed PR comments
parent
4a8c621f
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
54 additions
and
43 deletions
+54
-43
TokenSafetyModal.tsx
src/components/TokenSafety/TokenSafetyModal.tsx
+5
-8
index.tsx
src/components/TokenSafety/index.tsx
+6
-2
TokenDetail.tsx
src/components/Tokens/TokenDetails/TokenDetail.tsx
+3
-22
index.tsx
src/components/Widget/index.tsx
+4
-2
index.tsx
src/pages/TokenDetails/index.tsx
+33
-6
yarn.lock
yarn.lock
+3
-3
No files found.
src/components/TokenSafety/TokenSafetyModal.tsx
View file @
94dc3898
import
Modal
from
'
../Modal
'
import
Modal
from
'
../Modal
'
import
TokenSafety
from
'
.
'
import
TokenSafety
,
{
TokenSafetyProps
}
from
'
.
'
interface
TokenSafetyModalProps
{
interface
TokenSafetyModalProps
extends
TokenSafetyProps
{
isOpen
:
boolean
isOpen
:
boolean
tokenAddress
:
string
|
null
secondTokenAddress
?:
string
onContinue
:
()
=>
void
onCancel
:
()
=>
void
showCancel
?:
boolean
}
}
export
default
function
TokenSafetyModal
({
export
default
function
TokenSafetyModal
({
...
@@ -16,6 +11,7 @@ export default function TokenSafetyModal({
...
@@ -16,6 +11,7 @@ export default function TokenSafetyModal({
secondTokenAddress
,
secondTokenAddress
,
onContinue
,
onContinue
,
onCancel
,
onCancel
,
onBlocked
,
showCancel
,
showCancel
,
}:
TokenSafetyModalProps
)
{
}:
TokenSafetyModalProps
)
{
return
(
return
(
...
@@ -23,8 +19,9 @@ export default function TokenSafetyModal({
...
@@ -23,8 +19,9 @@ export default function TokenSafetyModal({
<
TokenSafety
<
TokenSafety
tokenAddress=
{
tokenAddress
}
tokenAddress=
{
tokenAddress
}
secondTokenAddress=
{
secondTokenAddress
}
secondTokenAddress=
{
secondTokenAddress
}
onCancel=
{
onCancel
}
onContinue=
{
onContinue
}
onContinue=
{
onContinue
}
onBlocked=
{
onBlocked
}
onCancel=
{
onCancel
}
showCancel=
{
showCancel
}
showCancel=
{
showCancel
}
/>
/>
</
Modal
>
</
Modal
>
...
...
src/components/TokenSafety/index.tsx
View file @
94dc3898
...
@@ -73,11 +73,13 @@ const Buttons = ({
...
@@ -73,11 +73,13 @@ const Buttons = ({
warning
,
warning
,
onContinue
,
onContinue
,
onCancel
,
onCancel
,
onBlocked
,
showCancel
,
showCancel
,
}:
{
}:
{
warning
:
Warning
warning
:
Warning
onContinue
:
()
=>
void
onContinue
:
()
=>
void
onCancel
:
()
=>
void
onCancel
:
()
=>
void
onBlocked
?:
()
=>
void
showCancel
?:
boolean
showCancel
?:
boolean
})
=>
{
})
=>
{
return
warning
.
canProceed
?
(
return
warning
.
canProceed
?
(
...
@@ -88,7 +90,7 @@ const Buttons = ({
...
@@ -88,7 +90,7 @@ const Buttons = ({
{
showCancel
&&
<
StyledCancelButton
onClick=
{
onCancel
}
>
Cancel
</
StyledCancelButton
>
}
{
showCancel
&&
<
StyledCancelButton
onClick=
{
onCancel
}
>
Cancel
</
StyledCancelButton
>
}
</>
</>
)
:
(
)
:
(
<
StyledCloseButton
onClick=
{
onCancel
}
>
<
StyledCloseButton
onClick=
{
on
Blocked
??
on
Cancel
}
>
<
Trans
>
Close
</
Trans
>
<
Trans
>
Close
</
Trans
>
</
StyledCloseButton
>
</
StyledCloseButton
>
)
)
...
@@ -184,11 +186,12 @@ const StyledExternalLink = styled(ExternalLink)`
...
@@ -184,11 +186,12 @@ const StyledExternalLink = styled(ExternalLink)`
font-weight: 600;
font-weight: 600;
`
`
interface
TokenSafetyProps
{
export
interface
TokenSafetyProps
{
tokenAddress
:
string
|
null
tokenAddress
:
string
|
null
secondTokenAddress
?:
string
secondTokenAddress
?:
string
onContinue
:
()
=>
void
onContinue
:
()
=>
void
onCancel
:
()
=>
void
onCancel
:
()
=>
void
onBlocked
?:
()
=>
void
showCancel
?:
boolean
showCancel
?:
boolean
}
}
...
@@ -197,6 +200,7 @@ export default function TokenSafety({
...
@@ -197,6 +200,7 @@ export default function TokenSafety({
secondTokenAddress
,
secondTokenAddress
,
onContinue
,
onContinue
,
onCancel
,
onCancel
,
onBlocked
,
showCancel
,
showCancel
,
}:
TokenSafetyProps
)
{
}:
TokenSafetyProps
)
{
const
logos
=
[]
const
logos
=
[]
...
...
src/components/Tokens/TokenDetails/TokenDetail.tsx
View file @
94dc3898
...
@@ -4,18 +4,16 @@ import { useWeb3React } from '@web3-react/core'
...
@@ -4,18 +4,16 @@ import { useWeb3React } from '@web3-react/core'
import
CurrencyLogo
from
'
components/CurrencyLogo
'
import
CurrencyLogo
from
'
components/CurrencyLogo
'
import
PriceChart
from
'
components/Tokens/TokenDetails/PriceChart
'
import
PriceChart
from
'
components/Tokens/TokenDetails/PriceChart
'
import
{
VerifiedIcon
}
from
'
components/TokenSafety/TokenSafetyIcon
'
import
{
VerifiedIcon
}
from
'
components/TokenSafety/TokenSafetyIcon
'
import
TokenSafetyModal
from
'
components/TokenSafety/TokenSafetyModal
'
import
{
getChainInfo
}
from
'
constants/chainInfo
'
import
{
getChainInfo
}
from
'
constants/chainInfo
'
import
{
nativeOnChain
,
WRAPPED_NATIVE_CURRENCY
}
from
'
constants/tokens
'
import
{
nativeOnChain
,
WRAPPED_NATIVE_CURRENCY
}
from
'
constants/tokens
'
import
{
checkWarning
,
WARNING_LEVEL
}
from
'
constants/tokenSafety
'
import
{
checkWarning
}
from
'
constants/tokenSafety
'
import
{
chainIdToChainName
,
useTokenDetailQuery
}
from
'
graphql/data/TokenDetailQuery
'
import
{
chainIdToChainName
,
useTokenDetailQuery
}
from
'
graphql/data/TokenDetailQuery
'
import
{
useCurrency
,
use
IsUserAddedToken
,
use
Token
}
from
'
hooks/Tokens
'
import
{
useCurrency
,
useToken
}
from
'
hooks/Tokens
'
import
{
useAtomValue
}
from
'
jotai/utils
'
import
{
useAtomValue
}
from
'
jotai/utils
'
import
{
darken
}
from
'
polished
'
import
{
darken
}
from
'
polished
'
import
{
Suspense
,
useCallback
}
from
'
react
'
import
{
Suspense
}
from
'
react
'
import
{
useState
}
from
'
react
'
import
{
useState
}
from
'
react
'
import
{
ArrowLeft
}
from
'
react-feather
'
import
{
ArrowLeft
}
from
'
react-feather
'
import
{
useNavigate
}
from
'
react-router-dom
'
import
styled
from
'
styled-components/macro
'
import
styled
from
'
styled-components/macro
'
import
{
CopyContractAddress
}
from
'
theme
'
import
{
CopyContractAddress
}
from
'
theme
'
import
{
formatDollarAmount
}
from
'
utils/formatDollarAmt
'
import
{
formatDollarAmount
}
from
'
utils/formatDollarAmt
'
...
@@ -178,17 +176,6 @@ export default function LoadedTokenDetail({ address }: { address: string }) {
...
@@ -178,17 +176,6 @@ export default function LoadedTokenDetail({ address }: { address: string }) {
const
isFavorited
=
useIsFavorited
(
address
)
const
isFavorited
=
useIsFavorited
(
address
)
const
toggleFavorite
=
useToggleFavorite
(
address
)
const
toggleFavorite
=
useToggleFavorite
(
address
)
const
warning
=
checkWarning
(
address
)
const
warning
=
checkWarning
(
address
)
const
navigate
=
useNavigate
()
const
isUserAddedToken
=
useIsUserAddedToken
(
token
)
const
[
warningModalOpen
,
setWarningModalOpen
]
=
useState
(
!!
warning
&&
!
isUserAddedToken
)
const
handleDismissWarning
=
useCallback
(()
=>
{
setWarningModalOpen
(
false
)
},
[
setWarningModalOpen
])
const
handleCancel
=
useCallback
(()
=>
{
setWarningModalOpen
(
false
)
warning
&&
warning
.
level
===
WARNING_LEVEL
.
BLOCKED
&&
navigate
(
-
1
)
},
[
setWarningModalOpen
,
navigate
,
warning
])
const
chainInfo
=
getChainInfo
(
token
?.
chainId
)
const
chainInfo
=
getChainInfo
(
token
?.
chainId
)
const
networkLabel
=
chainInfo
?.
label
const
networkLabel
=
chainInfo
?.
label
const
networkBadgebackgroundColor
=
chainInfo
?.
backgroundColor
const
networkBadgebackgroundColor
=
chainInfo
?.
backgroundColor
...
@@ -286,12 +273,6 @@ export default function LoadedTokenDetail({ address }: { address: string }) {
...
@@ -286,12 +273,6 @@ export default function LoadedTokenDetail({ address }: { address: string }) {
</
ContractAddress
>
</
ContractAddress
>
</
Contract
>
</
Contract
>
</
ContractAddressSection
>
</
ContractAddressSection
>
<
TokenSafetyModal
isOpen=
{
warningModalOpen
}
tokenAddress=
{
address
}
onCancel=
{
handleCancel
}
onContinue=
{
handleDismissWarning
}
/>
</
TopArea
>
</
TopArea
>
</
Suspense
>
</
Suspense
>
)
)
...
...
src/components/Widget/index.tsx
View file @
94dc3898
import
{
Currency
,
SwapWidget
}
from
'
@uniswap/widgets
'
import
{
Currency
,
OnReviewSwapClick
,
SwapWidget
}
from
'
@uniswap/widgets
'
import
{
useWeb3React
}
from
'
@web3-react/core
'
import
{
useWeb3React
}
from
'
@web3-react/core
'
import
{
RPC_URLS
}
from
'
constants/networks
'
import
{
RPC_URLS
}
from
'
constants/networks
'
import
{
useActiveLocale
}
from
'
hooks/useActiveLocale
'
import
{
useActiveLocale
}
from
'
hooks/useActiveLocale
'
...
@@ -16,9 +16,10 @@ const WIDGET_ROUTER_URL = 'https://api.uniswap.org/v1/'
...
@@ -16,9 +16,10 @@ const WIDGET_ROUTER_URL = 'https://api.uniswap.org/v1/'
export
interface
WidgetProps
{
export
interface
WidgetProps
{
defaultToken
?:
Currency
defaultToken
?:
Currency
onReviewSwapClick
?:
OnReviewSwapClick
}
}
export
default
function
Widget
({
defaultToken
}:
WidgetProps
)
{
export
default
function
Widget
({
defaultToken
,
onReviewSwapClick
}:
WidgetProps
)
{
const
locale
=
useActiveLocale
()
const
locale
=
useActiveLocale
()
const
darkMode
=
useIsDarkMode
()
const
darkMode
=
useIsDarkMode
()
const
theme
=
useMemo
(()
=>
(
darkMode
?
DARK_THEME
:
LIGHT_THEME
),
[
darkMode
])
const
theme
=
useMemo
(()
=>
(
darkMode
?
DARK_THEME
:
LIGHT_THEME
),
[
darkMode
])
...
@@ -38,6 +39,7 @@ export default function Widget({ defaultToken }: WidgetProps) {
...
@@ -38,6 +39,7 @@ export default function Widget({ defaultToken }: WidgetProps) {
width=
{
WIDGET_WIDTH
}
width=
{
WIDGET_WIDTH
}
locale=
{
locale
}
locale=
{
locale
}
theme=
{
theme
}
theme=
{
theme
}
onReviewSwapClick=
{
onReviewSwapClick
}
// defaultChainId is excluded - it is always inferred from the passed provider
// defaultChainId is excluded - it is always inferred from the passed provider
provider=
{
provider
}
provider=
{
provider
}
{
...
inputs
}
{
...
inputs
}
...
...
src/pages/TokenDetails/index.tsx
View file @
94dc3898
...
@@ -11,14 +11,15 @@ import LoadingTokenDetail from 'components/Tokens/TokenDetails/LoadingTokenDetai
...
@@ -11,14 +11,15 @@ import LoadingTokenDetail from 'components/Tokens/TokenDetails/LoadingTokenDetai
import
NetworkBalance
from
'
components/Tokens/TokenDetails/NetworkBalance
'
import
NetworkBalance
from
'
components/Tokens/TokenDetails/NetworkBalance
'
import
TokenDetail
from
'
components/Tokens/TokenDetails/TokenDetail
'
import
TokenDetail
from
'
components/Tokens/TokenDetails/TokenDetail
'
import
TokenSafetyMessage
from
'
components/TokenSafety/TokenSafetyMessage
'
import
TokenSafetyMessage
from
'
components/TokenSafety/TokenSafetyMessage
'
import
TokenSafetyModal
from
'
components/TokenSafety/TokenSafetyModal
'
import
Widget
,
{
WIDGET_WIDTH
}
from
'
components/Widget
'
import
Widget
,
{
WIDGET_WIDTH
}
from
'
components/Widget
'
import
{
getChainInfo
}
from
'
constants/chainInfo
'
import
{
getChainInfo
}
from
'
constants/chainInfo
'
import
{
L1_CHAIN_IDS
,
L2_CHAIN_IDS
,
SupportedChainId
,
TESTNET_CHAIN_IDS
}
from
'
constants/chains
'
import
{
L1_CHAIN_IDS
,
L2_CHAIN_IDS
,
SupportedChainId
,
TESTNET_CHAIN_IDS
}
from
'
constants/chains
'
import
{
checkWarning
}
from
'
constants/tokenSafety
'
import
{
checkWarning
}
from
'
constants/tokenSafety
'
import
{
useToken
}
from
'
hooks/Tokens
'
import
{
use
IsUserAddedToken
,
use
Token
}
from
'
hooks/Tokens
'
import
{
useNetworkTokenBalances
}
from
'
hooks/useNetworkTokenBalances
'
import
{
useNetworkTokenBalances
}
from
'
hooks/useNetworkTokenBalances
'
import
{
use
Memo
}
from
'
react
'
import
{
use
Callback
,
useMemo
,
useState
}
from
'
react
'
import
{
Navigate
,
useLocation
,
useParams
}
from
'
react-router-dom
'
import
{
Navigate
,
useLocation
,
use
Navigate
,
use
Params
}
from
'
react-router-dom
'
import
styled
from
'
styled-components/macro
'
import
styled
from
'
styled-components/macro
'
const
Footer
=
styled
.
div
`
const
Footer
=
styled
.
div
`
...
@@ -79,10 +80,28 @@ export default function TokenDetails() {
...
@@ -79,10 +80,28 @@ export default function TokenDetails() {
const
location
=
useLocation
()
const
location
=
useLocation
()
const
{
tokenAddress
}
=
useParams
<
{
tokenAddress
?:
string
}
>
()
const
{
tokenAddress
}
=
useParams
<
{
tokenAddress
?:
string
}
>
()
const
token
=
useToken
(
tokenAddress
)
const
token
=
useToken
(
tokenAddress
)
const
tokenWarning
=
tokenAddress
?
checkWarning
(
tokenAddress
)
:
null
const
isBlockedToken
=
tokenWarning
?.
canProceed
===
false
const
navigate
=
useNavigate
()
const
[
continueSwap
,
setContinueSwap
]
=
useState
<
{
resolve
:
(
value
:
boolean
|
PromiseLike
<
boolean
>
)
=>
void
}
>
()
const
shouldShowSpeedbump
=
!
useIsUserAddedToken
(
token
)
&&
tokenWarning
!==
null
// Show token safety modal if Swap-reviewing a warning token, at all times if the current token is blocked
const
onReviewSwap
=
useCallback
(()
=>
{
return
new
Promise
<
boolean
>
((
resolve
)
=>
{
shouldShowSpeedbump
?
setContinueSwap
({
resolve
})
:
resolve
(
true
)
})
},
[
shouldShowSpeedbump
])
const
onResolveSwap
=
useCallback
(
(
value
:
boolean
)
=>
{
continueSwap
?.
resolve
(
value
)
setContinueSwap
(
undefined
)
},
[
continueSwap
,
setContinueSwap
]
)
const
tokenWarning
=
token
?
checkWarning
(
token
.
address
)
:
null
/* network balance handling */
/* network balance handling */
const
{
data
:
networkData
}
=
NetworkBalances
(
token
?.
address
)
const
{
data
:
networkData
}
=
NetworkBalances
(
token
?.
address
)
const
{
chainId
:
connectedChainId
}
=
useWeb3React
()
const
{
chainId
:
connectedChainId
}
=
useWeb3React
()
const
totalBalance
=
4.3
// dummy data
const
totalBalance
=
4.3
// dummy data
...
@@ -128,7 +147,7 @@ export default function TokenDetails() {
...
@@ -128,7 +147,7 @@ export default function TokenDetails() {
<>
<>
<
TokenDetail
address=
{
token
.
address
}
/>
<
TokenDetail
address=
{
token
.
address
}
/>
<
RightPanel
>
<
RightPanel
>
<
Widget
defaultToken=
{
token
??
undefined
}
/>
<
Widget
defaultToken=
{
token
??
undefined
}
onReviewSwapClick=
{
onReviewSwap
}
/>
{
tokenWarning
&&
<
TokenSafetyMessage
tokenAddress=
{
token
.
address
}
warning=
{
tokenWarning
}
/>
}
{
tokenWarning
&&
<
TokenSafetyMessage
tokenAddress=
{
token
.
address
}
warning=
{
tokenWarning
}
/>
}
<
BalanceSummary
address=
{
token
.
address
}
/>
<
BalanceSummary
address=
{
token
.
address
}
/>
</
RightPanel
>
</
RightPanel
>
...
@@ -139,6 +158,14 @@ export default function TokenDetails() {
...
@@ -139,6 +158,14 @@ export default function TokenDetails() {
networkBalances=
{
balancesByNetwork
}
networkBalances=
{
balancesByNetwork
}
/>
/>
</
Footer
>
</
Footer
>
<
TokenSafetyModal
isOpen=
{
isBlockedToken
||
!!
continueSwap
}
tokenAddress=
{
token
.
address
}
onContinue=
{
()
=>
onResolveSwap
(
true
)
}
onBlocked=
{
()
=>
navigate
(
-
1
)
}
onCancel=
{
()
=>
onResolveSwap
(
false
)
}
showCancel=
{
true
}
/>
</>
</>
)
}
)
}
</
TokenDetailsLayout
>
</
TokenDetailsLayout
>
...
...
yarn.lock
View file @
94dc3898
...
@@ -5103,9 +5103,9 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5:
...
@@ -5103,9 +5103,9 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5:
uri-js "^4.2.2"
uri-js "^4.2.2"
ajv@^8.0.1:
ajv@^8.0.1:
version "8.
6.2
"
version "8.
11.0
"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.
6.2.tgz#2fb45e0e5fcbc0813326c1c3da535d1881bb0571
"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.
11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f
"
integrity sha512-
9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w
==
integrity sha512-
wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg
==
dependencies:
dependencies:
fast-deep-equal "^3.1.1"
fast-deep-equal "^3.1.1"
json-schema-traverse "^1.0.0"
json-schema-traverse "^1.0.0"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment