import React, { useCallback, useState } from 'react'; import { View, StyleSheet, InteractionManager, Text, LayoutAnimation, } from 'react-native'; import { strings } from '../../../../locales/i18n'; import ActionView from '../ActionView'; import AssetSearch from '../AssetSearch'; import AssetList from '../AssetList'; import Engine from '../../../core/Engine'; import AnalyticsV2 from '../../../util/analyticsV2'; import Alert, { AlertType } from '../../Base/Alert'; import FontAwesome from 'react-native-vector-icons/FontAwesome'; import { useSelector } from 'react-redux'; import { FORMATTED_NETWORK_NAMES } from '../../../constants/on-ramp'; import NotificationManager from '../../../core/NotificationManager'; import { useAppThemeFromContext, mockTheme } from '../../../util/theme'; const createStyles = (colors: any) => StyleSheet.create({ wrapper: { backgroundColor: colors.background.default, flex: 1, }, tokenDetectionBanner: { marginHorizontal: 20, marginTop: 20, paddingRight: 0, }, tokenDetectionDescription: { color: colors.text.default }, tokenDetectionLink: { color: colors.primary.default }, tokenDetectionIcon: { paddingTop: 4, paddingRight: 8, }, }); interface Props { /** /* navigation object required to push new views */ navigation: any; } /** * Component that provides ability to add searched assets with metadata. */ const SearchTokenAutocomplete = ({ navigation }: Props) => { const [searchResults, setSearchResults] = useState([]); const [searchQuery, setSearchQuery] = useState(''); const [selectedAsset, setSelectedAsset] = useState({}); const [isSearchFocused, setIsSearchFocused] = useState(false); const { address, symbol, decimals, image } = selectedAsset as any; const { colors } = useAppThemeFromContext() || mockTheme; const styles = createStyles(colors); const isTokenDetectionEnabled = useSelector( (state: any) => state.engine.backgroundState.PreferencesController.useTokenDetection, ); const chainId = useSelector( (state: any) => state.engine.backgroundState.NetworkController.provider.chainId, ); const networkType = useSelector( (state: any) => state.engine.backgroundState.NetworkController.provider.type, ); const setFocusState = useCallback( (isFocused: boolean) => { LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); setIsSearchFocused(isFocused); }, [setIsSearchFocused], ); const getAnalyticsParams = useCallback(() => { try { return { token_address: address, token_symbol: symbol, network_name: networkType, chain_id: chainId, source: 'Add token dropdown', }; } catch (error) { return {}; } }, [address, symbol, chainId, networkType]); const cancelAddToken = useCallback(() => { navigation.goBack(); }, [navigation]); const handleSearch = useCallback( (opts: any) => { setSearchResults(opts.results); setSearchQuery(opts.searchQuery); }, [setSearchResults, setSearchQuery], ); const handleSelectAsset = useCallback( (asset) => { setSelectedAsset(asset); }, [setSelectedAsset], ); const addToken = useCallback(async () => { const { TokensController } = Engine.context as any; await TokensController.addToken(address, symbol, decimals, image); AnalyticsV2.trackEvent( AnalyticsV2.ANALYTICS_EVENTS.TOKEN_ADDED as any, getAnalyticsParams(), ); // Clear state before closing setSearchResults([]); setSearchQuery(''); setSelectedAsset({}); InteractionManager.runAfterInteractions(() => { navigation.goBack(); NotificationManager.showSimpleNotification({ status: `simple_notification`, duration: 5000, title: strings('wallet.token_toast.token_imported_title'), description: strings('wallet.token_toast.token_imported_desc', { tokenSymbol: symbol, }), }); }); }, [ address, symbol, decimals, image, setSearchResults, setSearchQuery, setSelectedAsset, navigation, getAnalyticsParams, ]); const renderTokenDetectionBanner = useCallback(() => { if (isTokenDetectionEnabled || isSearchFocused) { return null; } return ( ( )} > <> {strings('add_asset.banners.search_desc', { network: FORMATTED_NETWORK_NAMES[chainId], })} { navigation.navigate('SettingsView', { screen: 'SettingsFlow', params: { screen: 'AdvancedSettings', params: { scrollToBottom: true, }, }, }); }} style={styles.tokenDetectionLink} > {strings('add_asset.banners.search_link')} ); }, [ navigation, isSearchFocused, isTokenDetectionEnabled, colors, styles, chainId, ]); return ( {renderTokenDetectionBanner()} { setFocusState(true); }} onBlur={() => setFocusState(false)} /> ); }; export default SearchTokenAutocomplete;