Skip to content

[410] Added interval on popular pools #1080

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

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
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
3 changes: 2 additions & 1 deletion src/components/PopularPools/Card/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const Card: React.FC<ICard> = ({
TVL,
apy,
// apyData,
poolAddress,
isLoading,
isUnknownFrom,
fee,
Expand Down Expand Up @@ -92,7 +93,7 @@ const Card: React.FC<ICard> = ({

return (
<Grid className={classes.root}>
{isLoading ? (
{isLoading || !poolAddress?.toString() ? (
<Skeleton variant='rounded' animation='wave' className={classes.skeleton} />
) : (
<Grid>
Expand Down
73 changes: 47 additions & 26 deletions src/components/PopularPools/PopularPools.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Grid, Typography, useMediaQuery } from '@mui/material'
import { Box, Grid, Typography, useMediaQuery } from '@mui/material'
import { useStyles } from './style'
import { PopularPoolData } from '@containers/PopularPoolsWrapper/PopularPoolsWrapper'
import Card from './Card/Card'
Expand All @@ -8,14 +8,26 @@ import 'slick-carousel/slick/slick.css'
import 'slick-carousel/slick/slick-theme.css'
import { theme } from '@static/theme'
import { useMemo } from 'react'
import Intervals from '@components/Stats/Intervals/Intervals'
import { Intervals as IntervalsKeys } from '@store/consts/static'

export interface IPopularPools {
pools: PopularPoolData[]
isLoading: boolean
network: NetworkType
showAPY: boolean
updateInterval: (interval: IntervalsKeys) => void
lastUsedInterval: IntervalsKeys | null
}

const PopularPools: React.FC<IPopularPools> = ({ pools, isLoading, network, showAPY }) => {
const PopularPools: React.FC<IPopularPools> = ({
pools,
isLoading,
network,
showAPY,
updateInterval,
lastUsedInterval
}) => {
const isLgDown = useMediaQuery(theme.breakpoints.down('lg'))
const isMdDown = useMediaQuery(theme.breakpoints.down('md'))
const isSmDown = useMediaQuery('@media (max-width:700px)')
Expand All @@ -31,9 +43,13 @@ const PopularPools: React.FC<IPopularPools> = ({ pools, isLoading, network, show

return (
<Grid container mb={6}>
<Typography className={classes.title} mb={3}>
Popular pools
</Typography>
<Box display='flex' alignItems='center' justifyContent='space-between' width='100%' mb={3}>
<Typography className={classes.title}>Popular pools</Typography>
<Intervals
interval={lastUsedInterval ?? IntervalsKeys.Daily}
setInterval={updateInterval}
/>
</Box>
<div className={classes.cardsContainer}>
<Slider
dots={isLgDown}
Expand All @@ -49,27 +65,32 @@ const PopularPools: React.FC<IPopularPools> = ({ pools, isLoading, network, show
dotsClass={`slick-dots ${classes.dots}`}
appendDots={dots => <ul>{dots}</ul>}
rows={1}>
{pools.map(pool => (
<Card
key={pool.addressFrom + pool.addressTo}
addressFrom={pool.addressFrom}
addressTo={pool.addressTo}
iconFrom={pool.iconFrom}
iconTo={pool.iconTo}
volume={pool.volume}
TVL={pool.TVL}
fee={pool.fee}
symbolFrom={pool.symbolFrom}
symbolTo={pool.symbolTo}
apy={pool.apy}
apyData={pool.apyData}
isUnknownFrom={pool.isUnknownFrom}
isUnknownTo={pool.isUnknownTo}
isLoading={isLoading}
network={network}
showAPY={showAPY}
/>
))}
{pools.map(pool => {
return (
(isLoading || (!isLoading && pool?.poolAddress)) && (
<Card
key={pool.addressFrom + pool.addressTo}
poolAddress={pool.poolAddress}
addressFrom={pool.addressFrom}
addressTo={pool.addressTo}
iconFrom={pool.iconFrom}
iconTo={pool.iconTo}
volume={pool.volume}
TVL={pool.TVL}
fee={pool.fee}
symbolFrom={pool.symbolFrom}
symbolTo={pool.symbolTo}
apy={pool.apy}
apyData={pool.apyData}
isUnknownFrom={pool.isUnknownFrom}
isUnknownTo={pool.isUnknownTo}
isLoading={isLoading}
network={network}
showAPY={showAPY}
/>
)
)
})}
</Slider>
</div>
</Grid>
Expand Down
3 changes: 2 additions & 1 deletion src/components/PopularPools/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ export const useStyles = makeStyles()(theme => ({
title: {
color: colors.invariant.text,
...typography.heading4,
fontWeight: 700
fontWeight: 700,
textWrap: 'nowrap'
},
cardsContainer: {
width: '100%',
Expand Down
2 changes: 1 addition & 1 deletion src/components/Stats/PoolListItem/PoolListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ const PoolListItem: React.FC<IProps> = ({
/>
</TooltipHover>
</Grid>
<Typography>{fee}%</Typography>
{fee && typeof fee === 'number' && <Typography>{fee}%</Typography>}
{!isSmd && showAPY ? (
<Grid className={classes.row} sx={{ justifyContent: 'space-between' }}>
<Grid sx={{ display: 'flex', gap: '4px' }}>
Expand Down
54 changes: 35 additions & 19 deletions src/containers/PopularPoolsWrapper/PopularPoolsWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import React, { useEffect, useMemo } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import React, { useMemo } from 'react'
import { useSelector } from 'react-redux'
import PopularPools from '@components/PopularPools/PopularPools'
import { isLoading, poolsStatsWithTokensDetails } from '@store/selectors/stats'
import { actions } from '@store/reducers/stats'
import { Grid } from '@mui/material'
import { network } from '@store/selectors/solanaConnection'
import { getPopularPools, Intervals } from '@store/consts/static'
import { unknownTokenIcon } from '@static/icons'
import { PublicKey } from '@solana/web3.js'
export interface PopularPoolData {
poolAddress?: PublicKey
symbolFrom?: string
symbolTo?: string
iconFrom?: string
Expand All @@ -25,9 +26,15 @@ export interface PopularPoolData {
isUnknownTo?: boolean
}

export const PopularPoolsWrapper: React.FC = () => {
const dispatch = useDispatch()
interface IPopularPoolsWrapper {
updateInterval: (interval: Intervals) => void
lastUsedInterval: Intervals | null
}

export const PopularPoolsWrapper: React.FC<IPopularPoolsWrapper> = ({
lastUsedInterval,
updateInterval
}) => {
const currentNetwork = useSelector(network)
const isLoadingStats = useSelector(isLoading)
const poolsList = useSelector(poolsStatsWithTokensDetails)
Expand Down Expand Up @@ -60,14 +67,11 @@ export const PopularPoolsWrapper: React.FC = () => {
return mockPools
}
if (popularPools.length === 0) {
popularPools = poolsList
.sort((a, b) => b.volume24 - a.volume24)
.slice(0, 4)
.map(pool => ({
tokenX: pool.tokenX.toString(),
tokenY: pool.tokenY.toString(),
fee: pool.fee.toString()
}))
popularPools = poolsList.slice(0, 4).map(pool => ({
tokenX: pool.tokenX.toString(),
tokenY: pool.tokenY.toString(),
fee: pool.fee.toString()
}))
}

popularPools.map(pool => {
Expand All @@ -79,6 +83,7 @@ export const PopularPoolsWrapper: React.FC = () => {
)
if (poolData) {
data.push({
poolAddress: poolData.poolAddress,
symbolFrom: poolData?.tokenXDetails?.symbol ?? pool.tokenX,
symbolTo: poolData?.tokenYDetails?.symbol ?? pool.tokenY,
iconFrom: poolData?.tokenXDetails?.logoURI ?? unknownTokenIcon,
Expand All @@ -97,8 +102,21 @@ export const PopularPoolsWrapper: React.FC = () => {
})
} else {
data.push({
addressFrom: pool.tokenX,
addressTo: pool.tokenY
symbolFrom: '-',
symbolTo: '-',
iconFrom: unknownTokenIcon,
iconTo: unknownTokenIcon,
volume: 0,
TVL: 0,
fee: 0,
addressFrom: pool.tokenX.toString(),
addressTo: pool.tokenY.toString(),
apy: 0,
apyData: {
fees: 0
},
isUnknownFrom: false,
isUnknownTo: false
})
}
})
Expand All @@ -110,17 +128,15 @@ export const PopularPoolsWrapper: React.FC = () => {
return list.some(pool => pool.apy !== 0)
}, [list])

useEffect(() => {
dispatch(actions.getCurrentIntervalStats({ interval: Intervals.Daily }))
}, [])

return (
<Grid container>
<PopularPools
pools={list}
isLoading={isLoadingStats || list.length === 0}
network={currentNetwork}
showAPY={showAPY}
lastUsedInterval={lastUsedInterval}
updateInterval={updateInterval}
/>
</Grid>
)
Expand Down
8 changes: 1 addition & 7 deletions src/containers/WrappedPoolList/WrappedPoolList.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import { Box, Typography, useMediaQuery } from '@mui/material'
import { isLoading, poolsStatsWithTokensDetails } from '@store/selectors/stats'
import { useEffect, useMemo, useState } from 'react'
import { useMemo, useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import useStyles from './styles'
import { VariantType } from 'notistack'
import { actions as snackbarActions } from '@store/reducers/snackbars'
import { network } from '@store/selectors/solanaConnection'
import { actions } from '@store/reducers/stats'
import LiquidityPoolList from '@components/LiquidityPoolList/LiquidityPoolList'
import { FilterSearch, ISearchToken } from '@common/FilterSearch/FilterSearch'
import { theme } from '@static/theme'
import { unknownTokenIcon } from '@static/icons'
import { Intervals } from '@store/consts/static'

export const WrappedPoolList: React.FC = () => {
const isXs = useMediaQuery(theme.breakpoints.down('sm'))
Expand Down Expand Up @@ -58,10 +56,6 @@ export const WrappedPoolList: React.FC = () => {
)
}

useEffect(() => {
dispatch(actions.getCurrentIntervalStats({ interval: Intervals.Daily }))
}, [dispatch])

return (
<div className={classes.container}>
<Box className={classes.rowContainer}>
Expand Down
25 changes: 24 additions & 1 deletion src/pages/ListPage/ListPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,36 @@ import { Grid } from '@mui/material'
import useStyles from './styles'
import PopularPoolsWrapper from '@containers/PopularPoolsWrapper/PopularPoolsWrapper'
import { WrappedPoolList } from '@containers/WrappedPoolList/WrappedPoolList'
import { useEffect } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { currentInterval } from '@store/selectors/stats'
import { Intervals as IntervalsKeys } from '@store/consts/static'
import { actions } from '@store/reducers/stats'

const ListPage: React.FC = () => {
const { classes } = useStyles()

const dispatch = useDispatch()

const lastUsedInterval = useSelector(currentInterval)

const updateInterval = (interval: IntervalsKeys) => {
dispatch(actions.getCurrentIntervalStats({ interval }))
dispatch(actions.setCurrentInterval({ interval }))
}

useEffect(() => {
dispatch(
actions.getCurrentIntervalStats({
interval: lastUsedInterval || IntervalsKeys.Daily
})
)
}, [])

return (
<Grid container className={classes.container}>
<Grid container className={classes.innerContainer}>
<PopularPoolsWrapper />
<PopularPoolsWrapper updateInterval={updateInterval} lastUsedInterval={lastUsedInterval} />
<WrappedPoolList />
</Grid>
</Grid>
Expand Down
6 changes: 2 additions & 4 deletions src/store/sagas/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@ import { poolsSaga } from './pool'
import { swapHandler } from './swap'
import { walletSaga } from './wallet'
import { positionsSaga } from './positions'
import { intervalStatsHandler } from './stats'
import { statsSaga } from './stats'

export function* rootSaga(): Generator {
yield all(
[connectionSaga, walletSaga, swapHandler, positionsSaga, poolsSaga, intervalStatsHandler].map(
spawn
)
[connectionSaga, walletSaga, swapHandler, positionsSaga, poolsSaga, statsSaga].map(spawn)
)
}
export default rootSaga
5 changes: 4 additions & 1 deletion src/store/sagas/stats.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { actions } from '@store/reducers/stats'
import { call, put, select, takeLatest } from 'typed-redux-saga'
import { all, call, put, select, spawn, takeLatest } from 'typed-redux-saga'
import { network } from '@store/selectors/solanaConnection'
import { ensureError, getIntervalsFullSnap } from '@utils/utils'
import { PublicKey } from '@solana/web3.js'
Expand Down Expand Up @@ -106,3 +106,6 @@ export function* getIntervalStats(action: PayloadAction<{ interval: Intervals }>
export function* intervalStatsHandler(): Generator {
yield* takeLatest(actions.getCurrentIntervalStats, getIntervalStats)
}
export function* statsSaga(): Generator {
yield* all([intervalStatsHandler].map(spawn))
}