Skip to content

Commit

Permalink
Feat/combine volume pool v2 v3 (#984)
Browse files Browse the repository at this point in the history
* feat: combined volume pool v2 & v3 in chart

* fix: chart show value

* fix: position list call rpc

* fix: clear interval incentive

---------

Co-authored-by: trungbach <trunga2k29@gmail.com>
  • Loading branch information
quangdz1704 and trungbach authored Oct 3, 2024
1 parent 6584526 commit 01e4807
Show file tree
Hide file tree
Showing 11 changed files with 351 additions and 72 deletions.
115 changes: 111 additions & 4 deletions src/pages/Pool-V3/components/PoolList/index.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,118 @@
width: 100%;
display: flex;
align-items: center;
gap: 12px;
flex-wrap: wrap;
border-radius: 12px;

@include small-mobile {
gap: 12px;
@include mobile() {
flex-direction: column;
align-items: flex-start;
}

@include theme() {
background-color: theme-get('neutral-surface-bg-section');
}

&_item {
display: flex;
padding: 16px;
flex-direction: column;
flex: 1 0 0;

color: $neutron-text-body-light;
font-size: 16px;
font-weight: 500;
line-height: 100%;

@include mobile() {
width: 100%;
}

.info {
display: flex;
align-items: center;
cursor: pointer;

.content {
display: flex;
flex-direction: column;
flex: 1;
gap: 16px;
}
}

.chart {
max-height: 0px;
padding: 0px 16px;
border-radius: 12px;
margin-top: 0px;

overflow: hidden;
transition: max-height ease-in-out 0.5s, padding ease-in-out 0.5s, margin-top ease-in-out 0.5s;

@include theme {
background: theme-get('neutral-surface-bg-2');
}

&.active {
padding: 16px;
margin-top: 16px;
max-height: 300px;
}
}

&:nth-child(even) {
border-start-end-radius: 12px;
border-end-end-radius: 12px;

@include theme() {
background-color: theme-get('neutral-surface-bg-section-3');
}

@include mobile {
border-radius: unset;
border-end-start-radius: 12px;
border-end-end-radius: 12px;
}
}

&_info {
display: flex;
align-items: flex-end;
gap: 8px;
align-self: stretch;

img {
width: 32px;
height: 32px;
}

svg {
width: 18px;
height: 18px;
}

.liq_value {
font-size: 24px;
font-weight: 500;
line-height: 120%;

/* 28.8px */
@include theme() {
color: theme-get('sea-stone-200');
}
}

.liq_suffix {
font-size: 16px;
font-weight: 500;
line-height: 150%;
color: $success-color;

&.negative {
color: $error-color;
}
}
}
}
}

Expand Down
77 changes: 71 additions & 6 deletions src/pages/Pool-V3/components/PoolList/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { BigDecimal, toDisplay } from '@oraichain/oraidex-common';
import { isMobile } from '@walletconnect/browser-utils';
import Loading from 'assets/gif/loading.gif';
import { ReactComponent as UpIcon } from 'assets/icons/up-arrow.svg';
import { ReactComponent as DownIcon } from 'assets/icons/down-arrow-v2.svg';
import { ReactComponent as SortDownIcon } from 'assets/icons/down_icon.svg';
import { ReactComponent as IconInfo } from 'assets/icons/infomationIcon.svg';
import { ReactComponent as SortUpIcon } from 'assets/icons/up_icon.svg';
Expand Down Expand Up @@ -29,6 +31,10 @@ import styles from './index.module.scss';
import PoolItemDataMobile from './PoolItemDataMobile';
import PoolItemTData from './PoolItemTData';
import { AddLiquidityModal } from 'pages/Pools/components/AddLiquidityModal';
import LiquidityChart from 'pages/Pools/components/LiquidityChart';
import VolumeChart from 'pages/Pools/components/VolumeChart';
import { FILTER_DAY } from 'reducer/type';
import TokenBalance from 'components/TokenBalance';

export enum PoolColumnHeader {
POOL_NAME = 'Pool name',
Expand Down Expand Up @@ -62,9 +68,38 @@ const PoolList = ({ search, filterType }: { search: string; filterType: POOL_TYP
const [totalLiquidity, setTotalLiquidity] = useState(0);
const { feeDailyData } = useGetFeeDailyData();
const { poolList: dataPool, poolPrice, loading } = useGetPoolList(price);
const { poolLiquidities, poolVolume, volumeV2, liquidityV2 } = useGetPoolLiquidityVolume(poolPrice);
const { poolLiquidities, poolVolume } = useGetPoolLiquidityVolume(poolPrice); // volumeV2, liquidityV2
const { poolPositionInfo } = useGetPoolPositionInfo(poolPrice);

const isMobileMode = isMobile();
const [openChart, setOpenChart] = useState(false); // !isMobileMode
const [filterDay, setFilterDay] = useState(FILTER_DAY.DAY);
const [liquidityDataChart, setLiquidityDataChart] = useState(0);
const [volumeDataChart, setVolumeDataChart] = useState(0);

const liquidityData = [
{
name: 'Total Liquidity',
Icon: null,
suffix: 5.25,
value: liquidityDataChart, // || statisticData.totalLiquidity,
isNegative: false,
decimal: 2,
chart: <LiquidityChart filterDay={filterDay} onUpdateCurrentItem={setLiquidityDataChart} />,
openChart: openChart
},
{
name: 'Volume',
Icon: null,
suffix: 3.93,
value: volumeDataChart,
isNegative: false,
decimal: 2,
chart: <VolumeChart filterDay={filterDay} onUpdateCurrentItem={setVolumeDataChart} />,
openChart: openChart
}
];

useEffect(() => {
const getAPRInfo = async () => {
const res = await fetchPoolAprInfo(dataPool, poolPrice, poolPositionInfo, feeDailyData);
Expand All @@ -91,8 +126,8 @@ const PoolList = ({ search, filterType }: { search: string; filterType: POOL_TYP
if (Object.values(poolVolume).length > 0) {
const totalVolume24h = Object.values(poolVolume).reduce((acc, cur) => acc + cur, 0);

const totalAllPoolVol = new BigDecimal(totalVolume24h).add(volumeV2).toNumber();
setTotalVolume(totalAllPoolVol);
// const totalAllPoolVol = new BigDecimal(totalVolume24h).add(volumeV2).toNumber();
setTotalVolume(totalVolume24h);
setVolumnePools(
Object.keys(poolVolume).map((poolAddress) => {
return {
Expand All @@ -113,8 +148,8 @@ const PoolList = ({ search, filterType }: { search: string; filterType: POOL_TYP
if (Object.values(poolLiquidities).length > 0) {
const totalLiqudity = Object.values(poolLiquidities).reduce((acc, cur) => acc + cur, 0);
setLiquidityPools(poolLiquidities);
const totalAllPoolLiq = new BigDecimal(totalLiqudity).add(liquidityV2).toNumber();
setTotalLiquidity(totalAllPoolLiq);
// const totalAllPoolLiq = new BigDecimal(totalLiqudity).add(liquidityV2).toNumber();
setTotalLiquidity(totalLiqudity);
}
}, [poolLiquidities, dataPool]);

Expand Down Expand Up @@ -360,7 +395,7 @@ const PoolList = ({ search, filterType }: { search: string; filterType: POOL_TYP
<div className={styles.poolList}>
<div className={styles.headerTable}>
<div className={styles.headerInfo}>
<div className={styles.total}>
{/* <div className={styles.total}>
<p>Total liquidity</p>
{totalLiquidity === 0 || totalLiquidity ? (
<h1>{formatDisplayUsdt(Number(totalLiquidity) || 0)}</h1>
Expand All @@ -375,6 +410,36 @@ const PoolList = ({ search, filterType }: { search: string; filterType: POOL_TYP
) : (
<img src={Loading} alt="loading" width={32} height={32} />
)}
</div> */}
<div className={styles.headerInfo}>
{liquidityData.map((e) => (
<div key={e.name} className={`${styles.headerInfo_item} ${openChart ? styles.activeChart : ''}`}>
<div className={styles.info} onClick={() => setOpenChart((open) => !open)}>
<div className={styles.content}>
<span>{e.name}</span>
<div className={styles.headerInfo_item_info}>
{e.Icon && (
<div>
<e.Icon />
</div>
)}
{!e.value ? (
<img src={Loading} alt="loading_img" />
) : (
<TokenBalance
balance={e.value}
prefix="$"
className={styles.liq_value}
decimalScale={e.decimal || 6}
/>
)}
</div>
</div>
<div>{e.value && openChart ? <UpIcon /> : <DownIcon />}</div>
</div>
<div className={`${styles.chart} ${e.value && openChart ? styles.active : ''}`}>{e.chart}</div>
</div>
))}
</div>
</div>
</div>
Expand Down
37 changes: 26 additions & 11 deletions src/pages/Pool-V3/components/PositionItem/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ import ZapOut from '../ZapOut';
import styles from './index.module.scss';
import { extractAddress } from 'pages/Pool-V3/helpers/format';

let intervalId = null;

const PositionItem = ({ position }) => {
const theme = useTheme();
const ref = useRef();
Expand Down Expand Up @@ -94,7 +96,7 @@ const PositionItem = ({ position }) => {
const { feeDailyData, refetchfeeDailyData } = useGetFeeDailyData();
const { refetchPositions } = useGetPositions(address);
const { poolList, poolPrice } = useGetPoolList(price);
const { simulation } = useGetIncentiveSimulate(address, position.id);
const { simulation, refetchGetIncentiveSimulate } = useGetIncentiveSimulate(address, position.id, openCollapse);

useOnClickOutside(ref, () => {
setCollapse(false);
Expand Down Expand Up @@ -133,6 +135,7 @@ const PositionItem = ({ position }) => {

useEffect(() => {
if (!openCollapse) return;

(async () => {
try {
const { pool_key, lower_tick_index, upper_tick_index } = position;
Expand Down Expand Up @@ -184,18 +187,30 @@ const PositionItem = ({ position }) => {
}, [position, poolList]);

useEffect(() => {
if (Object.keys(simulation).length > 0 && openCollapse && incentives) {
const intervalId = setInterval(() => {
const newIncentives: Record<string, number> = {};
for (const [key, value] of Object.entries(simulation)) {
newIncentives[key] = value + (incentives[key] || 0);
(async () => {
if (openCollapse && incentives) {
if (Object.keys(simulation).length <= 0) {
await refetchGetIncentiveSimulate();
} else {
intervalId = setInterval(async () => {
const newIncentives: Record<string, number> = {};
for (const [key, value] of Object.entries(simulation)) {
newIncentives[key] = value + (incentives[key] || 0);
}

setIncentives(newIncentives);
}, 2000);
}
setIncentives(newIncentives);
}, 2000);
return () => {
}

if (intervalId && !openCollapse) {
clearInterval(intervalId);
};
}
}
})();

return () => {
clearInterval(intervalId);
};
}, [openCollapse, incentives, simulation]);

const earnXDisplay = toDisplay((earnX || 0).toString(), tokenXDecimal);
Expand Down
35 changes: 20 additions & 15 deletions src/pages/Pool-V3/components/PositionList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,15 @@ const PositionList = () => {
const [cachePrices] = useConfigReducer('coingecko');
const [address] = useConfigReducer('address');

const [loading, setLoading] = useState(false);
const [dataPosition, setDataPosition] = useState<any[]>([]);
const { positions, isFetchingPositions } = useGetPositions(address);
const { poolList, poolPrice } = useGetPoolList(cachePrices);

useEffect(() => {
(async () => {
try {
// setLoading(true);
if (!address) {
setDataPosition([]);
return;
Expand All @@ -47,6 +50,8 @@ const PositionList = () => {
setDataPosition(positionsMap);
} catch (error) {
console.error('Failed to fetch data:', error);
} finally {
// setLoading(false);
}
})();

Expand All @@ -55,22 +60,22 @@ const PositionList = () => {

return (
<div className={styles.positionList}>
{/* <LoadingBox loading={loading} styles={{ minHeight: '60vh', height: 'fit-content' }}> */}
{dataPosition.length
? dataPosition.map((position, key) => {
return (
<div className={styles.item} key={`position-list-item-${key}`}>
<PositionItem position={position} />
</div>
);
})
: (
<div className={styles.nodata}>
{theme === 'light' ? <NoData /> : <NoDataDark />}
<span>No Positions!</span>
<LoadingBox loading={loading} styles={{ minHeight: '60vh', height: 'fit-content' }}>
{dataPosition.length ? (
dataPosition.map((position, key) => {
return (
<div className={styles.item} key={`position-list-item-${key}`}>
<PositionItem position={position} />
</div>
)}
{/* </LoadingBox> */}
);
})
) : (
<div className={styles.nodata}>
{theme === 'light' ? <NoData /> : <NoDataDark />}
<span>No Positions!</span>
</div>
)}
</LoadingBox>
</div>
);
};
Expand Down
3 changes: 2 additions & 1 deletion src/pages/Pool-V3/hooks/useGetIncentiveSimulate.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { useQuery } from '@tanstack/react-query';
import SingletonOraiswapV3 from 'libs/contractSingleton';

export const useGetIncentiveSimulate = (owner: string, positionIndex: number) => {
export const useGetIncentiveSimulate = (owner: string, positionIndex: number, openCollapse: boolean) => {
const { data: simulation, refetch: refetchGetIncentiveSimulate } = useQuery<Record<string, number>>(
['pool-v3-incentive-simulate', owner, positionIndex],
() => SingletonOraiswapV3.simulateIncentiveReward(owner, positionIndex),
{
refetchOnWindowFocus: false,
placeholderData: {},
enabled: !!openCollapse && !!positionIndex && !!owner
// cacheTime: 5 * 60 * 1000
}
);
Expand Down
Loading

0 comments on commit 01e4807

Please sign in to comment.