diff --git a/src/components/organisms/AssetActions/Pool/Graph.tsx b/src/components/organisms/AssetActions/Pool/Graph.tsx index decddd491..9c217d61a 100644 --- a/src/components/organisms/AssetActions/Pool/Graph.tsx +++ b/src/components/organisms/AssetActions/Pool/Graph.tsx @@ -17,8 +17,9 @@ import { darkModeConfig } from '../../../../../app.config' import Button from '../../../atoms/Button' import { Logger } from '@oceanprotocol/lib' import { useAsset } from '../../../../providers/Asset' -import { gql, useQuery } from 'urql' +import { gql, OperationContext, OperationResult } from 'urql' import { PoolHistory } from '../../../../@types/apollo/PoolHistory' +import { getSubgrahUri, fetchData } from '../../../../utils/subgraph' declare type GraphType = 'liquidity' | 'price' @@ -27,6 +28,8 @@ defaults.global.defaultFontFamily = `'Sharp Sans', -apple-system, BlinkMacSystem 'Segoe UI', Helvetica, Arial, sans-serif` defaults.global.animation = { easing: 'easeInOutQuart', duration: 1000 } +const REFETCH_INTERVAL = 10000 + const lineStyle: Partial = { fill: false, lineTension: 0.1, @@ -121,24 +124,58 @@ export default function Graph(): ReactElement { const [options, setOptions] = useState() const [graphType, setGraphType] = useState('liquidity') - const { price } = useAsset() + const { price, ddo } = useAsset() const [lastBlock, setLastBlock] = useState(0) const [priceHistory, setPriceHistory] = useState([]) + const [error, setError] = useState() const [liquidityHistory, setLiquidityHistory] = useState([]) const [timestamps, setTimestamps] = useState([]) const [isLoading, setIsLoading] = useState(true) + const [dataHistory, setDataHistory] = useState() const [graphData, setGraphData] = useState() + const [graphFetchInterval, setGraphFetchInterval] = useState() - const [result, refetch] = useQuery({ - query: poolHistory, - variables: { - id: price.address.toLowerCase(), - block: lastBlock + async function getPoolHistory() { + try { + const queryContext: OperationContext = { + url: `${getSubgrahUri( + Number(ddo.chainId) + )}/subgraphs/name/oceanprotocol/ocean-subgraph`, + requestPolicy: 'network-only' + } + const queryVariables = { + id: price.address.toLowerCase(), + block: lastBlock + } + + const queryResult: OperationResult = await fetchData( + poolHistory, + queryVariables, + queryContext + ) + setDataHistory(queryResult?.data) + } catch (error) { + console.error('Error fetchData: ', error.message) + setError(error) } - // pollInterval: 20000 - }) - const { data, error } = result + } + + function refetchGraph() { + if (!graphFetchInterval) { + setGraphFetchInterval( + setInterval(function () { + getPoolHistory() + }, REFETCH_INTERVAL) + ) + } + } + + useEffect(() => { + return () => { + clearInterval(graphFetchInterval) + } + }, [graphFetchInterval]) useEffect(() => { Logger.log('Fired GraphOptions!') @@ -147,59 +184,70 @@ export default function Graph(): ReactElement { }, [locale, darkMode.value]) useEffect(() => { - if (!data) return - Logger.log('Fired GraphData!') + getPoolHistory() + }, [lastBlock]) - const latestTimestamps = [ - ...timestamps, - ...data.poolTransactions.map((item) => { - const date = new Date(item.timestamp * 1000) - return `${date.toLocaleDateString()} ${date.toLocaleTimeString()}` - }) - ] - setTimestamps(latestTimestamps) + useEffect(() => { + async function init() { + const data: PoolHistory = dataHistory + if (!data) { + await getPoolHistory() + return + } + Logger.log('Fired GraphData!') - const latestLiquidtyHistory = [ - ...liquidityHistory, - ...data.poolTransactions.map((item) => item.oceanReserve) - ] + const latestTimestamps = [ + ...timestamps, + ...data.poolTransactions.map((item) => { + const date = new Date(item.timestamp * 1000) + return `${date.toLocaleDateString()} ${date.toLocaleTimeString()}` + }) + ] + setTimestamps(latestTimestamps) - setLiquidityHistory(latestLiquidtyHistory) + const latestLiquidtyHistory = [ + ...liquidityHistory, + ...data.poolTransactions.map((item) => item.oceanReserve) + ] - const latestPriceHistory = [ - ...priceHistory, - ...data.poolTransactions.map((item) => item.spotPrice) - ] + setLiquidityHistory(latestLiquidtyHistory) - setPriceHistory(latestPriceHistory) + const latestPriceHistory = [ + ...priceHistory, + ...data.poolTransactions.map((item) => item.spotPrice) + ] - if (data.poolTransactions.length > 0) { - const newBlock = - data.poolTransactions[data.poolTransactions.length - 1].block - if (newBlock === lastBlock) return - setLastBlock( - data.poolTransactions[data.poolTransactions.length - 1].block - ) - refetch() - } else { - setGraphData({ - labels: latestTimestamps.slice(0), - datasets: [ - { - ...lineStyle, - label: 'Liquidity (OCEAN)', - data: - graphType === 'liquidity' - ? latestLiquidtyHistory.slice(0) - : latestPriceHistory.slice(0), - borderColor: `#8b98a9`, - pointBackgroundColor: `#8b98a9` - } - ] - }) - setIsLoading(false) + setPriceHistory(latestPriceHistory) + + if (data.poolTransactions.length > 0) { + const newBlock = + data.poolTransactions[data.poolTransactions.length - 1].block + if (newBlock === lastBlock) return + setLastBlock( + data.poolTransactions[data.poolTransactions.length - 1].block + ) + } else { + setGraphData({ + labels: latestTimestamps.slice(0), + datasets: [ + { + ...lineStyle, + label: 'Liquidity (OCEAN)', + data: + graphType === 'liquidity' + ? latestLiquidtyHistory.slice(0) + : latestPriceHistory.slice(0), + borderColor: `#8b98a9`, + pointBackgroundColor: `#8b98a9` + } + ] + }) + setIsLoading(false) + refetchGraph() + } } - }, [data, graphType]) + init() + }, [dataHistory, graphType]) function handleGraphTypeSwitch(e: ChangeEvent) { e.preventDefault() diff --git a/src/components/organisms/AssetActions/Pool/index.tsx b/src/components/organisms/AssetActions/Pool/index.tsx index a413beed8..6ba89b7f6 100644 --- a/src/components/organisms/AssetActions/Pool/index.tsx +++ b/src/components/organisms/AssetActions/Pool/index.tsx @@ -15,10 +15,13 @@ import { PoolBalance } from '../../../../@types/TokenBalance' import Transactions from './Transactions' import Graph from './Graph' import { useAsset } from '../../../../providers/Asset' -import { gql, useQuery } from 'urql' +import { gql, OperationResult, OperationContext } from 'urql' import { PoolLiquidity } from '../../../../@types/apollo/PoolLiquidity' import { useOcean } from '../../../../providers/Ocean' import { useWeb3 } from '../../../../providers/Web3' +import { getSubgrahUri, fetchData } from '../../../../utils/subgraph' + +const REFETCH_INTERVAL = 5000 const contentQuery = graphql` query PoolQuery { @@ -89,23 +92,55 @@ export default function Pool(): ReactElement { const [creatorLiquidity, setCreatorLiquidity] = useState() const [creatorPoolTokens, setCreatorPoolTokens] = useState() const [creatorPoolShare, setCreatorPoolShare] = useState() + const [dataLiquidity, setdataLiquidity] = useState() + const [liquidityFetchInterval, setLiquidityFetchInterval] = + useState() // the purpose of the value is just to trigger the effect const [refreshPool, setRefreshPool] = useState(false) - const [result] = useQuery({ - query: poolLiquidityQuery, - variables: { + + async function getPoolLiquidity() { + const queryContext: OperationContext = { + url: `${getSubgrahUri( + Number(ddo.chainId) + )}/subgraphs/name/oceanprotocol/ocean-subgraph`, + requestPolicy: 'network-only' + } + const queryVariables = { id: price.address.toLowerCase(), shareId: `${price.address.toLowerCase()}-${ddo.publicKey[0].owner.toLowerCase()}` } - // pollInterval: 5000 - }) - const { data: dataLiquidity } = result + const queryResult: OperationResult = await fetchData( + poolLiquidityQuery, + queryVariables, + queryContext + ) + setdataLiquidity(queryResult?.data) + } + + function refetchLiquidity() { + if (!liquidityFetchInterval) { + setLiquidityFetchInterval( + setInterval(function () { + getPoolLiquidity() + }, REFETCH_INTERVAL) + ) + } + } + + useEffect(() => { + return () => { + clearInterval(liquidityFetchInterval) + } + }, [liquidityFetchInterval]) useEffect(() => { async function init() { - if (!dataLiquidity || !dataLiquidity.pool) return + if (!dataLiquidity || !dataLiquidity.pool) { + await getPoolLiquidity() + return + } // Total pool shares const totalPoolTokens = dataLiquidity.pool.totalShares @@ -153,6 +188,7 @@ export default function Pool(): ReactElement { creatorLiquidity && ((Number(creatorPoolTokens) / Number(totalPoolTokens)) * 100).toFixed(2) setCreatorPoolShare(creatorPoolShare) + refetchLiquidity() } init() }, [dataLiquidity, ddo.dataToken, price.datatoken, price.ocean, price?.value]) diff --git a/src/utils/subgraph.ts b/src/utils/subgraph.ts index dbafc0b34..6cc7b5355 100644 --- a/src/utils/subgraph.ts +++ b/src/utils/subgraph.ts @@ -141,12 +141,12 @@ const HighestLiquidityAssets = gql` } ` -function getSubgrahUri(chainId: number): string { +export function getSubgrahUri(chainId: number): string { const config = getOceanConfig(chainId) return config.subgraphUri } -async function fetchData( +export async function fetchData( query: TypedDocumentNode, variables: any, context: OperationContext @@ -157,6 +157,7 @@ async function fetchData( return response } catch (error) { console.error('Error fetchData: ', error.message) + throw Error(error.message) } }