Skip to content

Commit

Permalink
fix: fix polling
Browse files Browse the repository at this point in the history
  • Loading branch information
salimtb committed Nov 14, 2024
1 parent 92576bf commit 2663782
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 93 deletions.
160 changes: 69 additions & 91 deletions app/components/UI/Tokens/TokenList/TokenListItem/index.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,31 @@
import React, { useCallback } from 'react';
import React from 'react';
import { View } from 'react-native';
import { Hex } from '@metamask/utils';
import { zeroAddress } from 'ethereumjs-util';
import { useSelector } from 'react-redux';
import { useNavigation } from '@react-navigation/native';
import useTokenBalancesController from '../../../../hooks/useTokenBalancesController/useTokenBalancesController';
import useIsOriginalNativeTokenSymbol from '../../../../hooks/useIsOriginalNativeTokenSymbol/useIsOriginalNativeTokenSymbol';
import { useTheme } from '../../../../../util/theme';
import { TOKEN_RATE_UNDEFINED } from '../../constants';
import { deriveBalanceFromAssetMarketDetails } from '../../util/deriveBalanceFromAssetMarketDetails';
import {
selectContractExchangeRates,
selectTokenMarketData,
} from '../../../../../selectors/tokenRatesController';
selectChainId,
selectProviderConfig,
selectTicker,
} from '../../../../../selectors/networkController';
import { selectContractExchangeRates } from '../../../../../selectors/tokenRatesController';
import {
selectConversionRate,
selectCurrentCurrency,
} from '../../../../../selectors/currencyRateController';
import { selectNetworkName } from '../../../../../selectors/networkInfos';
import { RootState } from '../../../../../reducers';
import { safeToChecksumAddress } from '../../../../../util/address';
import {
getTestNetImageByChainId,
isLineaMainnetByChainId,
isMainnetByChainId,
isTestNet,
} from '../../../../../util/networks';
import createStyles from '../../styles';
Expand All @@ -26,17 +40,16 @@ import Text, {
} from '../../../../../component-library/components/Texts/Text';
import PercentageChange from '../../../../../component-library/components-temp/Price/PercentageChange';
import AssetElement from '../../../AssetElement';
import NetworkAssetLogo from '../../../NetworkAssetLogo';
import NetworkMainAssetLogo from '../../../NetworkMainAssetLogo';
import images from 'images/image-icons';
import { TokenI } from '../../types';
import { strings } from '../../../../../../locales/i18n';
import { ScamWarningIcon } from '../ScamWarningIcon';
import { ScamWarningModal } from '../ScamWarningModal';
import { StakeButton } from '../../../Stake/components/StakeButton';
import { CHAIN_ID_TOKEN_IMAGE_MAP } from '../../../../../util/networks/networks';
import { CustomNetworkImgMapping } from '../../../../../util/networks/customNetworks';
import useStakingChain from '../../../Stake/hooks/useStakingChain';
import {
PopularList,
UnpopularNetworkList,
} from '../../../../../util/networks/customNetworks';

interface TokenListItemProps {
asset: TokenI;
showScamWarningModal: boolean;
Expand All @@ -54,57 +67,40 @@ export const TokenListItem = ({
}: TokenListItemProps) => {
const navigation = useNavigation();
const { colors } = useTheme();
// const { data: tokenBalances } = useTokenBalancesController();

// const { type } = useSelector(selectProviderConfig);
// const chainId = useSelector(selectChainId);
// const ticker = useSelector(selectTicker);
// const isOriginalNativeTokenSymbol = useIsOriginalNativeTokenSymbol(
// chainId,
// ticker,
// type,
// );
const { data: tokenBalances } = useTokenBalancesController();

const { type } = useSelector(selectProviderConfig);
const chainId = useSelector(selectChainId);
const ticker = useSelector(selectTicker);
const isOriginalNativeTokenSymbol = useIsOriginalNativeTokenSymbol(
chainId,
ticker,
type,
);
const tokenExchangeRates = useSelector(selectContractExchangeRates);
// const currentCurrency = useSelector(selectCurrentCurrency);
// const conversionRate = useSelector(selectConversionRate);
const currentCurrency = useSelector(selectCurrentCurrency);
const conversionRate = useSelector(selectConversionRate);
const networkName = useSelector(selectNetworkName);
// const primaryCurrency = useSelector(
// (state: RootState) => state.settings.primaryCurrency,
// );
const multiChainMarketData = useSelector(selectTokenMarketData);
// console.log('multiChainMarketData', multiChainMarketData);
const primaryCurrency = useSelector(
(state: RootState) => state.settings.primaryCurrency,
);

const styles = createStyles(colors);

const itemAddress = safeToChecksumAddress(asset.address);

// const { balanceFiat, balanceValueFormatted } =
// deriveBalanceFromAssetMarketDetails(
// asset,
// tokenExchangeRates,
// tokenBalances,
// conversionRate,
// currentCurrency,
// );

// const pricePercentChange1d = itemAddress
// ? tokenExchangeRates?.[itemAddress as `0x${string}`]?.pricePercentChange1d
// : tokenExchangeRates?.[zeroAddress() as Hex]?.pricePercentChange1d;

// const pricePercentChange1d =
// multiChainMarketData?.[asset.chainId as HexString]?.[
// asset.address as HexString
// ]?.pricePercentChange1d;

const tokenPercentageChange = asset.address
? multiChainMarketData?.[asset.chainId as HexString]?.[
asset.address as HexString
]?.pricePercentChange1d
: null;
const { balanceFiat, balanceValueFormatted } =
deriveBalanceFromAssetMarketDetails(
asset,
tokenExchangeRates,
tokenBalances,
conversionRate,
currentCurrency,
);

const pricePercentChange1d = asset.isNative
? multiChainMarketData?.[asset.chainId as HexString]?.[zeroAddress()]
?.pricePercentChange1d
: tokenPercentageChange;
const pricePercentChange1d = itemAddress
? tokenExchangeRates?.[itemAddress as `0x${string}`]?.pricePercentChange1d
: tokenExchangeRates?.[zeroAddress() as Hex]?.pricePercentChange1d;

// render balances according to primary currency
let mainBalance;
Expand Down Expand Up @@ -153,36 +149,26 @@ export const TokenListItem = ({
secondaryBalance = strings('wallet.unable_to_find_conversion_rate');
}

const { isStakingSupportedChain } = useStakingChain();

const getNetworkBadgeSrc = useCallback((currentChainId: HexString) => {
if (isTestNet(currentChainId))
return getTestNetImageByChainId(currentChainId);
asset = { ...asset, balanceFiat };

const defaultNetwork = getDefaultNetworkByChainId(currentChainId) as any;
const isMainnet = isMainnetByChainId(chainId);
const isLineaMainnet = isLineaMainnetByChainId(chainId);

if (defaultNetwork) {
return defaultNetwork.imageSource;
}
const { isStakingSupportedChain } = useStakingChain();

const unpopularNetwork = UnpopularNetworkList.find(
(networkConfig) => networkConfig.chainId === currentChainId,
);
const NetworkBadgeSource = () => {
if (isTestNet(chainId)) return getTestNetImageByChainId(chainId);

const customNetworkImg = CHAIN_ID_TOKEN_IMAGE_MAP[currentChainId];
if (isMainnet) return images.ETHEREUM;

const popularNetwork = PopularList.find(
(networkConfig) => networkConfig.chainId === currentChainId,
);
if (isLineaMainnet) return images['LINEA-MAINNET'];

const network = unpopularNetwork || popularNetwork;
if (network) {
return network.rpcPrefs.imageSource;
}
if (customNetworkImg) {
return customNetworkImg;
if (CustomNetworkImgMapping[chainId]) {
return CustomNetworkImgMapping[chainId];
}
}, []);

return ticker ? images[ticker] : undefined;
};

const onItemPress = (token: TokenI) => {
// if the asset is staked, navigate to the native asset details
Expand All @@ -201,28 +187,21 @@ export const TokenListItem = ({
onPress={onItemPress}
onLongPress={asset.isETH ? null : showRemoveMenu}
asset={asset}
balance={asset.balanceFiat}
mainBalance={asset.balance}
balance={secondaryBalance}
mainBalance={mainBalance}
privacyMode={privacyMode}
>
<BadgeWrapper
badgeElement={
<Badge
variant={BadgeVariant.Network}
imageSource={getNetworkBadgeSrc(asset.chainId as HexString)}
imageSource={NetworkBadgeSource()}
name={networkName}
/>
}
>
{asset.isNative ? (
<NetworkAssetLogo
chainId={asset.chainId as HexString}
style={styles.ethLogo}
ticker={asset.symbol}
big={false}
biggest={false}
testID={'PLACE HOLDER'}
/>
{asset.isETH ? (
<NetworkMainAssetLogo style={styles.ethLogo} />
) : (
<AvatarToken
name={asset.symbol}
Expand All @@ -247,8 +226,7 @@ export const TokenListItem = ({
<StakeButton asset={asset} />
)}
</View>
{/* TODO: Make sure this works later */}
{!isTestNet(asset.chainId as HexString) ? (
{!isTestNet(chainId) ? (
<PercentageChange value={pricePercentChange1d} />
) : null}
</View>
Expand Down
6 changes: 4 additions & 2 deletions app/components/hooks/AssetPolling/AssetPollingProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import React, { ReactNode } from 'react';
import useCurrencyRatePolling from './useCurrencyRatePolling';
import useTokenRatesPolling from './useTokenRatesPolling';
import useTokenList from '../DisplayName/useTokenList';
import useTokenBalancesPolling from './useTokenBalancesPolling';
import useTokenListPolling from './useTokenListPolling';

// This provider is a step towards making controller polling fully UI based.
// Eventually, individual UI components will call the use*Polling hooks to
// poll and return particular data. This polls globally in the meantime.
export const AssetPollingProvider = ({ children }: { children: ReactNode }) => {
useCurrencyRatePolling();
useTokenRatesPolling();
// useTokenList();
useTokenListPolling();
useTokenBalancesPolling();

return <>{children}</>;
};
35 changes: 35 additions & 0 deletions app/components/hooks/AssetPolling/useTokenBalancesPolling.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { useSelector } from 'react-redux';
import { selectNetworkConfigurations } from '../../../selectors/networkController';
import Engine from '../../../core/Engine';
import usePolling from '../usePolling';
import { selectTokensBalances } from '../../../selectors/tokenBalancesController';

const useTokenBalancesPolling = () => {
// Selectors to determine polling input
const networkConfigurations = useSelector(selectNetworkConfigurations);

const tokensBalances = useSelector(selectTokensBalances);

const input = Object.values(networkConfigurations).map(({ chainId }) => ({
chainId,
}));

const { TokenBalancesController } = Engine.context;

usePolling({
startPolling: TokenBalancesController.startPolling.bind(
TokenBalancesController,
),
stopPollingByPollingToken:
TokenBalancesController.stopPollingByPollingToken.bind(
TokenBalancesController,
),
input,
});

return {
tokensBalances,
};
};

export default useTokenBalancesPolling;

0 comments on commit 2663782

Please sign in to comment.