From f9f64426a788dd363eb353c289585a0b2dca6ecf Mon Sep 17 00:00:00 2001 From: quangdz1704 Date: Wed, 25 Sep 2024 18:02:37 +0700 Subject: [PATCH] feat: sort token list --- src/hooks/useCoingecko.ts | 14 ++++++++++---- .../Swap/components/SelectToken/SelectToken.tsx | 10 +++++++++- src/reducer/config.ts | 2 ++ src/store/constants.ts | 2 +- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/hooks/useCoingecko.ts b/src/hooks/useCoingecko.ts index fbafebe19..23af8a5a2 100644 --- a/src/hooks/useCoingecko.ts +++ b/src/hooks/useCoingecko.ts @@ -11,7 +11,7 @@ import { CoinGeckoId } from '@oraichain/oraidex-common'; */ export const buildCoinGeckoPricesURL = (tokens: readonly string[]): string => // `https://api.coingecko.com/api/v3/simple/price?ids=${tokens.join('%2C')}&vs_currencies=usd`; - `https://price.market.orai.io/simple/price?ids=${tokens.join('%2C')}&vs_currencies=usd`; + `https://price.market.orai.io/simple/price?ids=${tokens.join('%2C')}&vs_currencies=usd&include_24hr_vol=true`; /** * Prices of each token. @@ -32,6 +32,7 @@ export const useCoinGeckoPrices = ( // use cached first then update by query, if is limited then return cached version const [cachePrices, setCachePrices] = useConfigReducer('coingecko'); + const [tokenRank, setTokenRank] = useConfigReducer('tokenRank'); return useQuery({ initialData: cachePrices, @@ -39,8 +40,9 @@ export const useCoinGeckoPrices = ( // make unique queryKey: ['coinGeckoPrices', ...tokens], queryFn: async ({ signal }) => { - const prices = await getCoingeckoPrices(tokens, cachePrices, signal); + const { prices, ranks } = await getCoingeckoPrices(tokens, cachePrices, tokenRank, signal); setCachePrices(prices); + setTokenRank(ranks); return Object.fromEntries(tokens.map((token) => [token, prices[token]])) as CoinGeckoPrices; } @@ -50,11 +52,13 @@ export const useCoinGeckoPrices = ( export const getCoingeckoPrices = async ( tokens: string[], cachePrices?: CoinGeckoPrices, + cacheRank?: CoinGeckoPrices, signal?: AbortSignal -): Promise> => { +): Promise<{ prices: CoinGeckoPrices; ranks: CoinGeckoPrices }> => { const coingeckoPricesURL = buildCoinGeckoPricesURL(tokens); const prices = { ...cachePrices }; + const ranks = { ...cacheRank }; // by default not return data then use cached version try { @@ -62,15 +66,17 @@ export const getCoingeckoPrices = async ( const rawData = (await resp.json()) as { [C in T]?: { usd: number; + usd_24h_vol: number; }; }; // update cached for (const key in rawData) { prices[key] = rawData[key].usd; + ranks[key] = rawData[key].usd_24h_vol; } } catch { // remain old cache console.log('error getting coingecko prices: ', prices); } - return prices; + return { prices, ranks }; }; diff --git a/src/pages/UniversalSwap/Swap/components/SelectToken/SelectToken.tsx b/src/pages/UniversalSwap/Swap/components/SelectToken/SelectToken.tsx index d12c01ef0..2d6d361c2 100644 --- a/src/pages/UniversalSwap/Swap/components/SelectToken/SelectToken.tsx +++ b/src/pages/UniversalSwap/Swap/components/SelectToken/SelectToken.tsx @@ -12,6 +12,7 @@ import { toSumDisplay } from 'libs/utils'; import { formatDisplayUsdt } from 'pages/Pools/helpers'; import React, { useEffect, useState } from 'react'; import { getSubAmountDetails } from 'rest/api'; +import useConfigReducer from 'hooks/useConfigReducer'; const cx = cn.bind(styles); interface InputSwapProps { @@ -65,6 +66,8 @@ export default function SelectToken({ const [textChain, setTextChain] = useState(''); const [textSearch, setTextSearch] = useState(''); const isLightTheme = theme === 'light'; + const [tokenRank = {}] = useConfigReducer('tokenRank'); + useEffect(() => { if (selectChain && selectChain !== textChain) setTextChain(selectChain); }, [selectChain]); @@ -146,7 +149,12 @@ export default function SelectToken({ }; }) .sort((a, b) => { - return Number(b.usd) - Number(a.usd); + const balanceDelta = Number(b.usd) - Number(a.usd); + + if (!balanceDelta) { + return tokenRank[b.coinGeckoId] - tokenRank[a.coinGeckoId]; + } + return balanceDelta; }) .map(({ key, tokenIcon, networkIcon, balance, usd, ...token }) => { return ( diff --git a/src/reducer/config.ts b/src/reducer/config.ts index 9928ffcb8..39322d7ab 100644 --- a/src/reducer/config.ts +++ b/src/reducer/config.ts @@ -38,6 +38,7 @@ export interface ConfigState { hideOraichainSmallAmount: boolean; theme: Themes; coingecko: CoinGeckoPrices; + tokenRank: Record; apr: { [key: string]: number; }; @@ -83,6 +84,7 @@ const initialState: ConfigState = { hideOraichainSmallAmount: false, theme: 'dark', coingecko: {}, + tokenRank: {}, apr: {}, rewardPools: [], liquidityPools: {}, diff --git a/src/store/constants.ts b/src/store/constants.ts index 16499c485..f62845cc5 100644 --- a/src/store/constants.ts +++ b/src/store/constants.ts @@ -1,5 +1,5 @@ // change version when update, add state redux-persist storage -export const PERSIST_VER = 2.4; +export const PERSIST_VER = 2.5; export const PERSIST_CONFIG_KEY = 'root'; export const ADDRESS_BOOK_KEY_BACKUP = 'addressBookBackup';