Commit bc899b74 authored by lynn's avatar lynn Committed by GitHub

feat: make token safety speedbumps appear for tokens with warnings in token selector (#4496)

* checkpoint: token modal safety warning working, showing speedbump

* fix styling

* dont show token safety once user has already ack'd that token

* fix cancel button on token safety - always navigate back to search
parent 516c8b05
......@@ -128,7 +128,7 @@ function CurrencyRow({
eventProperties,
}: {
currency: Currency
onSelect: () => void
onSelect: (hasWarning: boolean) => void
isSelected: boolean
otherSelected: boolean
style: CSSProperties
......@@ -159,8 +159,8 @@ function CurrencyRow({
redesignFlag={redesignFlagEnabled}
style={style}
className={`token-item-${key}`}
onKeyPress={(e) => (!isSelected && e.key === 'Enter' ? onSelect() : null)}
onClick={() => (isSelected ? null : onSelect())}
onKeyPress={(e) => (!isSelected && e.key === 'Enter' ? onSelect(!!warning) : null)}
onClick={() => (isSelected ? null : onSelect(!!warning))}
disabled={isSelected}
selected={otherSelected}
>
......@@ -279,7 +279,7 @@ export default function CurrencyList({
currencies: Currency[]
otherListTokens?: WrappedTokenInfo[]
selectedCurrency?: Currency | null
onCurrencySelect: (currency: Currency) => void
onCurrencySelect: (currency: Currency, hasWarning?: boolean) => void
otherCurrency?: Currency | null
fixedListRef?: MutableRefObject<FixedSizeList | undefined>
showImportView: () => void
......@@ -308,7 +308,7 @@ export default function CurrencyList({
const isSelected = Boolean(currency && selectedCurrency && selectedCurrency.equals(currency))
const otherSelected = Boolean(currency && otherCurrency && otherCurrency.equals(currency))
const handleSelect = () => currency && onCurrencySelect(currency)
const handleSelect = (hasWarning: boolean) => currency && onCurrencySelect(currency, hasWarning)
const token = currency?.wrapped
......
......@@ -51,7 +51,7 @@ interface CurrencySearchProps {
isOpen: boolean
onDismiss: () => void
selectedCurrency?: Currency | null
onCurrencySelect: (currency: Currency) => void
onCurrencySelect: (currency: Currency, hasWarning?: boolean) => void
otherSelectedCurrency?: Currency | null
showCommonBases?: boolean
showCurrencyAmount?: boolean
......@@ -136,9 +136,9 @@ export function CurrencySearch({
}, [debouncedQuery, native, filteredSortedTokens])
const handleCurrencySelect = useCallback(
(currency: Currency) => {
onCurrencySelect(currency)
onDismiss()
(currency: Currency, hasWarning?: boolean) => {
onCurrencySelect(currency, hasWarning)
if (!hasWarning) onDismiss()
},
[onDismiss, onCurrencySelect]
)
......
......@@ -5,6 +5,7 @@ import { TokenSafetyVariant, useTokenSafetyFlag } from 'featureFlags/flags/token
import usePrevious from 'hooks/usePrevious'
import { useCallback, useEffect, useState } from 'react'
import { WrappedTokenInfo } from 'state/lists/wrappedTokenInfo'
import { useUserAddedTokens } from 'state/user/hooks'
import useLast from '../../hooks/useLast'
import Modal from '../Modal'
......@@ -29,6 +30,7 @@ export enum CurrencyModalView {
manage,
importToken,
importList,
tokenSafety,
}
export default function CurrencySearchModal({
......@@ -43,6 +45,7 @@ export default function CurrencySearchModal({
}: CurrencySearchModalProps) {
const [modalView, setModalView] = useState<CurrencyModalView>(CurrencyModalView.manage)
const lastOpen = useLast(isOpen)
const userAddedTokens = useUserAddedTokens()
useEffect(() => {
if (isOpen && !lastOpen) {
......@@ -50,12 +53,28 @@ export default function CurrencySearchModal({
}
}, [isOpen, lastOpen])
const showTokenSafetySpeedbump = (token: Token) => {
setWarningToken(token)
setModalView(CurrencyModalView.tokenSafety)
}
const tokenSafetyFlag = useTokenSafetyFlag()
const handleCurrencySelect = useCallback(
(currency: Currency) => {
(currency: Currency, hasWarning?: boolean) => {
if (
tokenSafetyFlag === TokenSafetyVariant.Enabled &&
hasWarning &&
currency.isToken &&
!userAddedTokens.find((token) => token.equals(currency))
) {
showTokenSafetySpeedbump(currency)
} else {
onCurrencySelect(currency)
onDismiss()
}
},
[onDismiss, onCurrencySelect]
[onDismiss, onCurrencySelect, tokenSafetyFlag, userAddedTokens]
)
// for token import view
......@@ -68,6 +87,9 @@ export default function CurrencySearchModal({
const [importList, setImportList] = useState<TokenList | undefined>()
const [listURL, setListUrl] = useState<string | undefined>()
// used for token safety
const [warningToken, setWarningToken] = useState<Token | undefined>()
const showImportView = useCallback(() => setModalView(CurrencyModalView.importToken), [setModalView])
const showManageView = useCallback(() => setModalView(CurrencyModalView.manage), [setModalView])
const handleBackImport = useCallback(
......@@ -75,8 +97,6 @@ export default function CurrencySearchModal({
[setModalView, prevView]
)
const tokenSafetyFlag = useTokenSafetyFlag()
// change min height if not searching
let minHeight: number | undefined = 80
let content = null
......@@ -98,17 +118,25 @@ export default function CurrencySearchModal({
/>
)
break
case CurrencyModalView.importToken:
if (importToken) {
case CurrencyModalView.tokenSafety:
minHeight = undefined
content =
tokenSafetyFlag === TokenSafetyVariant.Enabled ? (
if (tokenSafetyFlag === TokenSafetyVariant.Enabled && warningToken) {
content = (
<TokenSafety
tokenAddress={importToken.address}
onContinue={() => handleCurrencySelect(importToken)}
onCancel={handleBackImport}
tokenAddress={warningToken.address}
onContinue={() => handleCurrencySelect(warningToken)}
onCancel={() => setModalView(CurrencyModalView.search)}
/>
) : (
)
}
break
case CurrencyModalView.importToken:
if (importToken) {
minHeight = undefined
if (tokenSafetyFlag === TokenSafetyVariant.Enabled) {
showTokenSafetySpeedbump(importToken)
}
content = (
<ImportToken
tokens={[importToken]}
onDismiss={onDismiss}
......
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