Skip to content

Commit

Permalink
refactor: avoid usage of useTokensToSeach
Browse files Browse the repository at this point in the history
  • Loading branch information
BZahory committed May 9, 2024
1 parent 637d218 commit b140e19
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 77 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import React, { useMemo } from 'react';
import React from 'react';
import { useSelector } from 'react-redux';
import classnames from 'classnames';
import {
getNativeCurrencyImage,
getSelectedAccountCachedBalance,
} from '../../../../selectors';
import { getSelectedAccountCachedBalance } from '../../../../selectors';
import { getNativeCurrency } from '../../../../ducks/metamask/metamask';
import { useUserPreferencedCurrency } from '../../../../hooks/useUserPreferencedCurrency';
import { PRIMARY, SECONDARY } from '../../../../helpers/constants/common';
Expand All @@ -22,25 +19,19 @@ import { TokenListItem } from '../..';
import { Asset, Token } from './types';
import AssetComponent from './Asset';

const MAX_UNOWNED_TOKENS_RENDERED = 30;

type AssetListProps = {
handleAssetChange: (token: Token) => void;
asset: Asset;
tokenList: Token[];
// searchQuery and all attached logic (e.g., filteredTokenList) could be pulled up if appropriate for a future refactor
searchQuery: string;
};

export default function AssetList({
handleAssetChange,
asset,
tokenList,
searchQuery,
}: AssetListProps) {
const selectedToken = asset.details?.address;

const nativeCurrencyImage = useSelector(getNativeCurrencyImage);
const nativeCurrency = useSelector(getNativeCurrency);
const balanceValue = useSelector(getSelectedAccountCachedBalance);

Expand All @@ -66,49 +57,9 @@ export default function AssetList({
hideLabel: true,
});

const filteredTokenList = useMemo(() => {
const filteredTokens: Token[] = [];

let token: Token;
for (token of tokenList) {
if (
token.symbol?.toLowerCase().includes(searchQuery.toLowerCase()) &&
token.symbol !== nativeCurrency
) {
filteredTokens.push(token);
}

if (filteredTokens.length > MAX_UNOWNED_TOKENS_RENDERED) {
break;
}
}

// prepend native currency to token list if it matches search query
if (nativeCurrency?.toLowerCase().includes(searchQuery.toLowerCase())) {
filteredTokens.unshift({
address: null,
symbol: nativeCurrency,
decimals: 18,
image: nativeCurrencyImage,
balance: balanceValue,
string: primaryCurrencyProperties.value,
type: AssetType.native,
});
}

return filteredTokens;
}, [
tokenList,
searchQuery,
nativeCurrency,
nativeCurrencyImage,
balanceValue,
primaryCurrencyProperties.value,
]);

return (
<Box className="tokens-main-view-modal">
{filteredTokenList.map((token) => {
{tokenList.map((token) => {
const isSelected =
token.address?.toLowerCase() === selectedToken?.toLowerCase();
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import React, { useState, useCallback, useMemo } from 'react';

import { useSelector } from 'react-redux';
import isEqual from 'lodash/isEqual';
import { uniqBy } from 'lodash';
import { isEqual, uniqBy } from 'lodash';
import { Tab, Tabs } from '../../../ui/tabs';
import NftsItems from '../../../app/nfts-items/nfts-items';
import {
Expand Down Expand Up @@ -38,16 +37,27 @@ import { AssetType } from '../../../../../shared/constants/transaction';
import { useNftsCollections } from '../../../../hooks/useNftsCollections';
import ZENDESK_URLS from '../../../../helpers/constants/zendesk-url';
import {
getCurrentChainId,
getCurrentCurrency,
getNativeCurrencyImage,
getSelectedAccountCachedBalance,
getSelectedInternalAccount,
getShouldHideZeroBalanceTokens,
getTokenExchangeRates,
getTokenList,
} from '../../../../selectors';
import { getTokens } from '../../../../ducks/metamask/metamask';
import {
getConversionRate,
getNativeCurrency,
getTokens,
} from '../../../../ducks/metamask/metamask';
import { useTokenTracker } from '../../../../hooks/useTokenTracker';
import { getTopAssets } from '../../../../ducks/swaps/swaps';
import { getRenderableTokenData } from '../../../../hooks/useTokensToSearch';
import { useEqualityCheck } from '../../../../hooks/useEqualityCheck';
import { useTokensToSearch } from '../../../../hooks/useTokensToSearch';
import { TokenBucketPriority } from '../../../../../shared/constants/swaps';
import { useCurrencyDisplay } from '../../../../hooks/useCurrencyDisplay';
import { useUserPreferencedCurrency } from '../../../../hooks/useUserPreferencedCurrency';
import { PRIMARY } from '../../../../helpers/constants/common';
import AssetList from './AssetList';
import { Asset, Collection, Token } from './types';

Expand All @@ -60,6 +70,8 @@ type AssetPickerModalProps = {
sendingAssetSymbol?: string;
};

const MAX_UNOWNED_TOKENS_RENDERED = 30;

export function AssetPickerModal({
isOpen,
onClose,
Expand Down Expand Up @@ -111,6 +123,26 @@ export function AssetPickerModal({

const isDest = sendingAssetImage && sendingAssetSymbol;

const chainId = useSelector(getCurrentChainId);

const nativeCurrencyImage = useSelector(getNativeCurrencyImage);
const nativeCurrency = useSelector(getNativeCurrency);
const balanceValue = useSelector(getSelectedAccountCachedBalance);

const tokenConversionRates = useSelector(getTokenExchangeRates, isEqual);
const conversionRate = useSelector(getConversionRate);
const currentCurrency = useSelector(getCurrentCurrency);

const {
currency: primaryCurrency,
numberOfDecimals: primaryNumberOfDecimals,
} = useUserPreferencedCurrency(PRIMARY, { ethNumberOfDecimals: 4 });

const [, primaryCurrencyProperties] = useCurrencyDisplay(balanceValue, {
numberOfDecimals: primaryNumberOfDecimals,
currency: primaryCurrency,
});

const { address: selectedAddress } = useSelector(getSelectedInternalAccount);
const shouldHideZeroBalanceTokens = useSelector(
getShouldHideZeroBalanceTokens,
Expand All @@ -123,30 +155,86 @@ export function AssetPickerModal({
});

// Swaps token list
const tokenList = useSelector(getTokenList, isEqual);
const shuffledTokensList = useMemo(
() => Object.values(tokenList),
[tokenList],
);
const tokenList = useSelector(getTokenList) as Record<string, Token>;
const topTokens = useSelector(getTopAssets, isEqual);

const usersTokens = uniqBy([...tokensWithBalances, ...tokens], 'address');

const memoizedUsersTokens = useEqualityCheck(usersTokens);

const fromTokenList = useTokensToSearch({
usersTokens: memoizedUsersTokens,
topTokens,
shuffledTokensList,
tokenBucketPriority: TokenBucketPriority.owned,
});
const filteredTokenList = useMemo(() => {
const nativeToken = {
address: null,
symbol: nativeCurrency,
decimals: 18,
image: nativeCurrencyImage,
balance: balanceValue,
string: primaryCurrencyProperties.value,
type: AssetType.native,
};

const filteredTokens: Token[] = [];
// undefined would be the native token address
const filteredTokensAddresses = new Set<string | undefined>();

function* tokenGenerator() {
yield nativeToken;
for (const token of memoizedUsersTokens) {
yield token;
}
for (const token of Object.values(topTokens)) {
yield token;
}
for (const token of Object.values(tokenList)) {
yield token;
}
}

const toTokenList = useTokensToSearch({
usersTokens: memoizedUsersTokens,
let token: Token;
for (token of tokenGenerator()) {
if (
token.symbol?.toLowerCase().includes(searchQuery.toLowerCase()) &&
!filteredTokensAddresses.has(token.address?.toLowerCase())
) {
filteredTokensAddresses.add(token.address?.toLowerCase());
filteredTokens.push(
getRenderableTokenData(
token.address
? {
...token,
...tokenList[token.address.toLowerCase()],
type: AssetType.token,
}
: token,
tokenConversionRates,
conversionRate,
currentCurrency,
chainId,
tokenList,
),
);
}

if (filteredTokens.length > MAX_UNOWNED_TOKENS_RENDERED) {
break;
}
}

return filteredTokens;
}, [
memoizedUsersTokens,
topTokens,
shuffledTokensList,
tokenBucketPriority: TokenBucketPriority.top,
});
searchQuery,
nativeCurrency,
nativeCurrencyImage,
balanceValue,
primaryCurrencyProperties.value,
tokenConversionRates,
conversionRate,
currentCurrency,
chainId,
tokenList,
]);

const Search = useCallback(
() => (
Expand Down Expand Up @@ -216,9 +304,8 @@ export function AssetPickerModal({
<Search />
<AssetList
handleAssetChange={handleAssetChange}
searchQuery={searchQuery}
asset={asset}
tokenList={toTokenList}
tokenList={filteredTokenList}
/>
</>
) : (
Expand All @@ -238,9 +325,8 @@ export function AssetPickerModal({
<Search />
<AssetList
handleAssetChange={handleAssetChange}
searchQuery={searchQuery}
asset={asset}
tokenList={fromTokenList}
tokenList={filteredTokenList}
/>
</Tab>
}
Expand Down

0 comments on commit b140e19

Please sign in to comment.