Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fix performance issues on token selector in widget #451

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions widget/embedded/src/components/TokenList/TokenList.helpers.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { TokenWithBalance } from './TokenList.types';
import type { Token } from 'rango-sdk';

import { containsText } from '../../utils/common';

export const filterTokens = (list: TokenWithBalance[], searchedFor: string) =>
export const filterTokens = (list: Token[], searchedFor: string) =>
list.filter(
(token) =>
containsText(token.symbol, searchedFor) ||
Expand Down
22 changes: 10 additions & 12 deletions widget/embedded/src/components/TokenList/TokenList.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
/* eslint-disable @typescript-eslint/no-magic-numbers */
import type {
PropTypes,
RenderDescProps,
TokenWithBalance,
} from './TokenList.types';
import type { PropTypes, RenderDescProps } from './TokenList.types';
import type { Token } from 'rango-sdk';
import type { CommonProps } from 'react-window';

import { i18n } from '@lingui/core';
Expand All @@ -24,6 +21,7 @@ import React, { forwardRef, useEffect, useState } from 'react';
import { useAppStore } from '../../store/AppStore';
import { useWalletsStore } from '../../store/wallets';
import { generateRangeColors } from '../../utils/colors';
import { formatBalance } from '../../utils/wallets';

import { LoadingTokenList } from './LoadingTokenList';
import {
Expand Down Expand Up @@ -85,11 +83,11 @@ const renderDesc = (props: RenderDescProps) => {
export function TokenList(props: PropTypes) {
const { list, searchedFor = '', onChange, selectedBlockchain } = props;

const [tokens, setTokens] = useState<TokenWithBalance[]>(list);
const [tokens, setTokens] = useState<Token[]>(list);
const fetchStatus = useAppStore().fetchStatus;
const blockchains = useAppStore().blockchains();
const [hasNextPage, setHasNextPage] = useState<boolean>(true);
const loadingWallet = useWalletsStore.use.loading();
const { getBalanceFor, loading: loadingWallet } = useWalletsStore();
const { isTokenPinned } = useAppStore();

// eslint-disable-next-line react/display-name
Expand Down Expand Up @@ -134,7 +132,7 @@ export function TokenList(props: PropTypes) {
<VirtualizedList
Item={({ index, style }) => {
const token = tokens[index];

const tokenBalance = formatBalance(getBalanceFor(token));
const address = token.address || '';
const blockchain = blockchains.find(
(blockchain) => blockchain.name === token.blockchain
Expand Down Expand Up @@ -229,18 +227,18 @@ export function TokenList(props: PropTypes) {
<Skeleton variant="text" size="medium" width={50} />
</End>
) : (
tokens[index]?.balance && (
tokenBalance && (
<BalanceContainer>
<Typography variant="title" size="small">
{token.balance?.amount}
{tokenBalance.amount}
</Typography>
<div />
{token.balance?.usdValue && (
{tokenBalance.usdValue && (
<Typography
variant="body"
className="usd-value"
size="xsmall">
{`$${token.balance?.usdValue}`}
{`$${tokenBalance.usdValue}`}
</Typography>
)}
</BalanceContainer>
Expand Down
13 changes: 3 additions & 10 deletions widget/embedded/src/components/TokenList/TokenList.types.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
import type { Token } from 'rango-sdk';

export interface TokenWithBalance extends Token {
balance?: {
amount: string;
usdValue: string;
};
}

export interface PropTypes {
list: TokenWithBalance[];
list: Token[];
searchedFor?: string;
onChange: (token: TokenWithBalance) => void;
onChange: (token: Token) => void;
selectedBlockchain?: string;
}

Expand All @@ -22,7 +15,7 @@ export interface RenderDescProps {
name?: string | null;
address: string;
url: string;
token: TokenWithBalance;
token: Token;
customCssForTag: TagCSS;
customCssForTagTitle: TitleCSS;
}
Expand Down
1 change: 0 additions & 1 deletion widget/embedded/src/components/TokenList/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export { TokenList } from './TokenList';
export type { TokenWithBalance } from './TokenList.types';
5 changes: 2 additions & 3 deletions widget/embedded/src/containers/Wallets/Wallets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,14 @@ export const WidgetContext = createContext<WidgetContextInterface>({
});

function Main(props: PropsWithChildren<PropTypes>) {
const updateConfig = useAppStore().updateConfig;
const { updateConfig } = useAppStore();
const blockchains = useAppStore().blockchains();
const tokens = useAppStore().tokens();
const walletOptions: ProvidersOptions = {
walletConnectProjectId: props.config?.walletConnectProjectId,
};
const { providers } = useWalletProviders(props.config.wallets, walletOptions);
const disconnectWallet = useWalletsStore.use.disconnectWallet();
const connectWallet = useWalletsStore.use.connectWallet();
const { connectWallet, disconnectWallet } = useWalletsStore();
const onConnectWalletHandler = useRef<OnConnectHandler>();

useEffect(() => {
Expand Down
42 changes: 9 additions & 33 deletions widget/embedded/src/pages/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import { SwitchFromAndToButton } from '../components/SwitchFromAndTo';
import { errorMessages } from '../constants/errors';
import { navigationRoutes } from '../constants/navigationRoutes';
import {
BALANCE_MAX_DECIMALS,
BALANCE_MIN_DECIMALS,
PERCENTAGE_CHANGE_MAX_DECIMALS,
PERCENTAGE_CHANGE_MIN_DECIMALS,
TOKEN_AMOUNT_MAX_DECIMALS,
Expand All @@ -27,7 +25,7 @@ import { useWalletsStore } from '../store/wallets';
import { numberToString } from '../utils/numbers';
import { getPriceImpact, getPriceImpactLevel } from '../utils/quote';
import { canComputePriceImpact, getSwapButtonState } from '../utils/swap';
import { getBalanceFromWallet } from '../utils/wallets';
import { formatBalance } from '../utils/wallets';

const Container = styled('div', {
display: 'flex',
Expand Down Expand Up @@ -73,7 +71,7 @@ export function Home() {

const fetchMetaStatus = useAppStore().fetchStatus;

const connectedWallets = useWalletsStore.use.connectedWallets();
const { connectedWallets, getBalanceFor } = useWalletsStore();
const setCurrentPage = useUiStore.use.setCurrentPage();
const [showQuoteWarningModal, setShowQuoteWarningModal] = useState(false);
const layoutRef = useRef<HTMLDivElement>(null);
Expand Down Expand Up @@ -103,36 +101,14 @@ export function Home() {
needsToWarnEthOnPath,
});

const tokenBalance =
!!fromBlockchain && !!fromToken
? numberToString(
getBalanceFromWallet(
connectedWallets,
fromBlockchain?.name,
fromToken?.symbol,
fromToken?.address
)?.amount || '0',
BALANCE_MIN_DECIMALS,
BALANCE_MAX_DECIMALS
)
: '0';
const fromTokenBalance = fromToken ? getBalanceFor(fromToken) : null;

const fromTokenFormattedBalance =
formatBalance(fromTokenBalance)?.amount ?? '0';

const tokenBalanceReal =
!!fromBlockchain && !!fromToken
? numberToString(
getBalanceFromWallet(
connectedWallets,
fromBlockchain?.name,
fromToken?.symbol,
fromToken?.address
)?.amount || '0',
getBalanceFromWallet(
connectedWallets,
fromBlockchain?.name,
fromToken?.symbol,
fromToken?.address
)?.decimal
)
? numberToString(fromTokenBalance?.amount, fromTokenBalance?.decimals)
: '0';

useEffect(() => {
Expand Down Expand Up @@ -194,7 +170,7 @@ export function Home() {
label={i18n.t('From')}
mode="From"
onInputChange={setInputAmount}
balance={tokenBalance}
balance={fromTokenFormattedBalance}
chain={{
displayName: fromBlockchain?.displayName || '',
image: fromBlockchain?.logo || '',
Expand All @@ -220,7 +196,7 @@ export function Home() {
disabled={fetchMetaStatus === 'failed'}
loading={fetchMetaStatus === 'loading'}
onSelectMaxBalance={() => {
if (tokenBalance !== '0') {
if (fromTokenFormattedBalance !== '0') {
setInputAmount(tokenBalanceReal.split(',').join(''));
}
}}
Expand Down
9 changes: 3 additions & 6 deletions widget/embedded/src/pages/SelectSwapItemsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { useNavigateBack } from '../hooks/useNavigateBack';
import { useAppStore } from '../store/AppStore';
import { useQuoteStore } from '../store/quote';
import { useWalletsStore } from '../store/wallets';
import { getTokensBalanceFromWalletAndSort } from '../utils/wallets';
import { sortTokensByBalance } from '../utils/wallets';

interface PropTypes {
type: 'source' | 'destination';
Expand All @@ -32,7 +32,7 @@ export function SelectSwapItemsPage(props: PropTypes) {
setFromBlockchain,
setToBlockchain,
} = useQuoteStore();
const { connectedWallets } = useWalletsStore();
const getBalanceFor = useWalletsStore.use.getBalanceFor();
const [searchedFor, setSearchedFor] = useState<string>('');

const selectedBlockchain = type === 'source' ? fromBlockchain : toBlockchain;
Expand All @@ -47,10 +47,7 @@ export function SelectSwapItemsPage(props: PropTypes) {
blockchain: selectedBlockchainName,
searchFor: searchedFor,
});
const tokensList = getTokensBalanceFromWalletAndSort(
tokens,
connectedWallets
);
const tokensList = sortTokensByBalance(tokens, getBalanceFor);

// Actions
const updateBlockchain = (blockchain: BlockchainMeta) => {
Expand Down
5 changes: 2 additions & 3 deletions widget/embedded/src/store/quote.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { TokenWithBalance } from '../components/TokenList';
import type { Wallet } from '../types';
import type { PendingSwap } from '@rango-dev/queue-manager-rango-preset/dist/shared';
import type {
Expand Down Expand Up @@ -38,8 +37,8 @@ export interface QuoteState {
inputUsdValue: BigNumber | null;
outputAmount: BigNumber | null;
outputUsdValue: BigNumber | null;
fromToken: TokenWithBalance | null;
toToken: TokenWithBalance | null;
fromToken: Token | null;
toToken: Token | null;
quoteWalletsConfirmed: boolean;
selectedWallets: Wallet[];
quoteWarningsConfirmed: boolean;
Expand Down
Loading