Skip to content

Commit

Permalink
Merge pull request #45 from QuickSwap/update-swap-page-performance
Browse files Browse the repository at this point in the history
Swap page update
  • Loading branch information
FriskyHamTitz authored Jan 24, 2022
2 parents b010cc8 + 88785a6 commit 2cb8927
Show file tree
Hide file tree
Showing 7 changed files with 426 additions and 487 deletions.
122 changes: 122 additions & 0 deletions src/pages/SwapPage/LiquidityPoolRow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import React from 'react';
import { Box, Typography, useMediaQuery } from '@material-ui/core';
import { makeStyles, useTheme } from '@material-ui/core/styles';
import { GlobalConst } from 'constants/index';
import { DoubleCurrencyLogo } from 'components';
import { formatCompact, getDaysCurrentYear } from 'utils';
import { useCurrency } from 'hooks/Tokens';

const useStyles = makeStyles(({ palette }) => ({
liquidityContent: {
border: `1px solid ${palette.secondary.dark}`,
borderRadius: '10px',
marginBottom: '20px',
'& p': {
color: palette.text.primary,
fontWeight: 600,
},
},
}));

const LiquidityPoolRow: React.FC<{
pair: any;
key: number;
}> = ({ pair, key }) => {
const classes = useStyles();
const { palette, breakpoints } = useTheme();
const daysCurrentYear = getDaysCurrentYear();
const isMobile = useMediaQuery(breakpoints.down('xs'));

const dayVolumeUSD =
Number(
pair.oneDayVolumeUSD ? pair.oneDayVolumeUSD : pair.oneDayVolumeUntracked,
) *
GlobalConst.utils.FEEPERCENT *
daysCurrentYear *
100;
const trackReserveUSD = Number(
pair.oneDayVolumeUSD ? pair.trackedReserveUSD : pair.reserveUSD,
);
const apy =
isNaN(dayVolumeUSD) || trackReserveUSD === 0
? 0
: dayVolumeUSD / trackReserveUSD;
const liquidity = pair.trackedReserveUSD
? pair.trackedReserveUSD
: pair.reserveUSD;
const volume = pair.oneDayVolumeUSD
? pair.oneDayVolumeUSD
: pair.oneDayVolumeUntracked;
const token0 = useCurrency(pair.token0.id);
const token1 = useCurrency(pair.token1.id);
return (
<Box
key={key}
display='flex'
flexWrap='wrap'
className={classes.liquidityContent}
padding={2}
>
<Box display='flex' alignItems='center' width={isMobile ? 1 : 0.5}>
<DoubleCurrencyLogo
currency0={token0 ?? undefined}
currency1={token1 ?? undefined}
size={28}
/>
<Typography variant='body2' style={{ marginLeft: 12 }}>
{pair.token0.symbol.toUpperCase()} /{' '}
{pair.token1.symbol.toUpperCase()}
</Typography>
</Box>
<Box
width={isMobile ? 1 : 0.2}
mt={isMobile ? 2.5 : 0}
display='flex'
justifyContent='space-between'
>
{isMobile && (
<Typography variant='body2' style={{ color: palette.text.secondary }}>
TVL
</Typography>
)}
<Typography variant='body2'>${formatCompact(liquidity)}</Typography>
</Box>
<Box
width={isMobile ? 1 : 0.15}
mt={isMobile ? 1 : 0}
display='flex'
justifyContent='space-between'
>
{isMobile && (
<Typography variant='body2' style={{ color: palette.text.secondary }}>
24H Volume
</Typography>
)}
<Typography variant='body2'>${formatCompact(volume)}</Typography>
</Box>
<Box
width={isMobile ? 1 : 0.15}
mt={isMobile ? 1 : 0}
display='flex'
justifyContent={isMobile ? 'space-between' : 'flex-end'}
>
{isMobile && (
<Typography variant='body2' style={{ color: palette.text.secondary }}>
APY
</Typography>
)}
<Typography
variant='body2'
align='right'
style={{
color: apy < 0 ? palette.error.main : palette.success.main,
}}
>
{apy.toFixed(2)}%
</Typography>
</Box>
</Box>
);
};

export default React.memo(LiquidityPoolRow);
171 changes: 171 additions & 0 deletions src/pages/SwapPage/LiquidityPools.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
import React, { useEffect, useMemo, useState } from 'react';
import { Box, Divider, Typography, useMediaQuery } from '@material-ui/core';
import { KeyboardArrowUp, KeyboardArrowDown } from '@material-ui/icons';
import { makeStyles, useTheme } from '@material-ui/core/styles';
import { getTokenPairs, getBulkPairData, getEthPrice } from 'utils';
import { Token } from '@uniswap/sdk';
import LiquidityPoolRow from './LiquidityPoolRow';

const useStyles = makeStyles(({ palette }) => ({
liquidityMain: {
'& p': {
color: palette.text.secondary,
fontWeight: 600,
},
},
liquidityFilter: {
'& p': {
cursor: 'pointer',
marginRight: 20,
'&.active': {
color: palette.primary.main,
},
},
},
}));

const LiquidityPools: React.FC<{
token1: Token;
token2: Token;
}> = ({ token1, token2 }) => {
const classes = useStyles();
const { palette, breakpoints } = useTheme();
const isMobile = useMediaQuery(breakpoints.down('xs'));
const [liquidityPoolClosed, setLiquidityPoolClosed] = useState(false);
const [liquidityFilterIndex, setLiquidityFilterIndex] = useState(0);
const [tokenPairs, updateTokenPairs] = useState<any[] | null>(null);
const token1Address = token1.address.toLowerCase();
const token2Address = token2.address.toLowerCase();

const liquidityPairs = useMemo(
() =>
tokenPairs
? tokenPairs
.filter((pair: any) => {
if (liquidityFilterIndex === 0) {
return true;
} else if (liquidityFilterIndex === 1) {
return (
pair.token0.id === token1Address ||
pair.token1.id === token1Address
);
} else {
return (
pair.token0.id === token2Address ||
pair.token1.id === token2Address
);
}
})
.slice(0, 5)
: [],
[tokenPairs, liquidityFilterIndex, token1Address, token2Address],
);

useEffect(() => {
async function fetchTokenPairs() {
const [newPrice] = await getEthPrice();
const tokenPairs = await getTokenPairs(token1Address, token2Address);
const formattedPairs = tokenPairs
? tokenPairs.map((pair: any) => {
return pair.id;
})
: [];
const pairData = await getBulkPairData(formattedPairs, newPrice);
if (pairData) {
updateTokenPairs(pairData);
}
}
fetchTokenPairs();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [token1Address, token2Address]);

return (
<>
<Box
display='flex'
alignItems='center'
justifyContent='space-between'
marginBottom={liquidityPoolClosed ? 0 : '20px'}
>
<Box display='flex' alignItems='center'>
<Typography
variant='h6'
style={{ color: palette.text.primary, marginRight: 8 }}
>
Liquidity Pools{' '}
</Typography>
<Typography variant='body2' style={{ color: palette.text.secondary }}>
({token1.symbol?.toUpperCase()}, {token2.symbol?.toUpperCase()})
</Typography>
</Box>
<Box
display='flex'
style={{ cursor: 'pointer', color: palette.text.secondary }}
onClick={() => setLiquidityPoolClosed(!liquidityPoolClosed)}
>
{liquidityPoolClosed ? <KeyboardArrowDown /> : <KeyboardArrowUp />}
</Box>
</Box>
{!liquidityPoolClosed && (
<>
<Divider />
<Box width={1}>
<Box display='flex' padding={2} className={classes.liquidityMain}>
<Box
display='flex'
width={0.5}
className={classes.liquidityFilter}
>
<Typography
variant='body2'
className={liquidityFilterIndex === 0 ? 'active' : ''}
onClick={() => setLiquidityFilterIndex(0)}
>
All
</Typography>
<Typography
variant='body2'
className={liquidityFilterIndex === 1 ? 'active' : ''}
onClick={() => setLiquidityFilterIndex(1)}
>
{token1.symbol?.toUpperCase()}
</Typography>
<Typography
variant='body2'
className={liquidityFilterIndex === 2 ? 'active' : ''}
onClick={() => setLiquidityFilterIndex(2)}
>
{token2.symbol?.toUpperCase()}
</Typography>
</Box>
{!isMobile && (
<>
<Box width={0.2}>
<Typography variant='body2' align='left'>
TVL
</Typography>
</Box>
<Box width={0.15}>
<Typography variant='body2' align='left'>
24h Volume
</Typography>
</Box>
<Box width={0.15}>
<Typography variant='body2' align='right'>
APY
</Typography>
</Box>
</>
)}
</Box>
{liquidityPairs.map((pair: any, ind: any) => (
<LiquidityPoolRow pair={pair} key={ind} />
))}
</Box>
</>
)}
</>
);
};

export default LiquidityPools;
Loading

0 comments on commit 2cb8927

Please sign in to comment.