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