Skip to content

Commit

Permalink
update tokenDetail page and update ZLUX token icon
Browse files Browse the repository at this point in the history
  • Loading branch information
foxier25 committed Nov 27, 2024
1 parent 2640e39 commit 112e4b9
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 34 deletions.
55 changes: 33 additions & 22 deletions src/components/Tokens/TokenDetails/ChartSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import { isPricePoint, PricePoint } from 'graphql/data/util'
import { TimePeriod } from 'graphql/data/util'
import { useAtomValue } from 'jotai/utils'
import { pageTimePeriodAtom } from 'pages/TokenDetails'
import { startTransition, Suspense, useMemo } from 'react'
import { startTransition, Suspense, useMemo, useEffect, useState } from 'react'

import { PriceChart } from './PriceChart'
import TimePeriodSelector from './TimeSelector'
import { ti } from 'make-plural'
import { left } from '@popperjs/core'

function fillMissingTimestamps(priceHistory: any, interval: number, totalTime: number) {
if (!Array.isArray(priceHistory) || priceHistory.length === 0) {
Expand All @@ -20,19 +21,19 @@ function fillMissingTimestamps(priceHistory: any, interval: number, totalTime: n
priceHistory.sort((a, b) => a.timestamp - b.timestamp);
const currentTimestamp = Date.now() / 1000
const filledHistory = [];

for (let i = 0; i < priceHistory.length - 1; i++) {
const current = priceHistory[i];
const next = priceHistory[i + 1];

// Add the current object to the filled array
if(next.timestamp + totalTime >= currentTimestamp) {
if(current.timestamp + totalTime >= currentTimestamp) filledHistory.push(current);
if (next.timestamp + totalTime >= currentTimestamp) {
if (current.timestamp + totalTime >= currentTimestamp) filledHistory.push(current);

// Fill missing timestamps
let timestamp = current.timestamp + interval;
while (timestamp < next.timestamp) {
if(timestamp + totalTime >= currentTimestamp)
if (timestamp + totalTime >= currentTimestamp)
filledHistory.push({
...current, // Copy previous values
timestamp, // Update timestamp
Expand All @@ -47,8 +48,8 @@ function fillMissingTimestamps(priceHistory: any, interval: number, totalTime: n
return filledHistory;
}

function getTimeInterval(timePeriod:any) {
switch(timePeriod) {
function getTimeInterval(timePeriod: any) {
switch (timePeriod) {
case 0:
return [300, 3600];
case 1:
Expand All @@ -64,23 +65,34 @@ function getTimeInterval(timePeriod:any) {
}

function usePriceHistory(tokenPriceData: TokenPriceQuery, timePeriod: any): PricePoint[] | undefined {

const [priceHistory, setPriceHistory] = useState<PricePoint[] | undefined>(undefined);
const [timeInterval, totalTime] = getTimeInterval(timePeriod);
// Appends the current price to the end of the priceHistory array
const priceHistory = useMemo(() => {
const market = tokenPriceData.token?.market
const priceHistory = market?.priceHistory?.filter(isPricePoint)
// const priceHistory = market?.priceHistory?.filter(isPricePoint)
const currentPrice = market?.price?.value
if (Array.isArray(priceHistory) && currentPrice !== undefined) {
const timestamp = Date.now() / 1000
return fillMissingTimestamps([...priceHistory, { timestamp, value: currentPrice }], timeInterval, totalTime)
}
return priceHistory
}, [tokenPriceData])

return priceHistory
useEffect(() => {
const updatePriceHistory = () => {
const market = tokenPriceData.token?.market;
const history = market?.priceHistory?.filter(isPricePoint);
const currentPrice = market?.price?.value;

if (Array.isArray(history) && currentPrice !== undefined) {
const timestamp = Date.now() / 1000;
const filledHistory = fillMissingTimestamps([...history, { timestamp, value: currentPrice }], timeInterval, totalTime);
setPriceHistory(filledHistory);
} else {
setPriceHistory(history);
}
};

// Update immediately and then at intervals
updatePriceHistory();
const intervalId = setInterval(updatePriceHistory, 12000); // Update every 12 seconds

return () => clearInterval(intervalId); // Cleanup on component unmount
}, [tokenPriceData, timeInterval, totalTime]);

return priceHistory;
}

export default function ChartSection({
tokenPriceQuery,
onChangeTimePeriod,
Expand Down Expand Up @@ -112,7 +124,6 @@ function Chart({
// Initializes time period to global & maintain separate time period for subsequent changes
const timePeriod = useAtomValue(pageTimePeriodAtom)
const prices = usePriceHistory(tokenPriceQuery, timePeriod)
console.log(tokenPriceQuery, prices);

return (
<ChartContainer data-testid="chart-container">
Expand Down
68 changes: 57 additions & 11 deletions src/pages/TokenDetails/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { luxNetClient } from 'graphql/thegraph/apollo'
import { zooNetClient } from 'graphql/thegraph/apollo'

const GetTokenInfo = gql`
query GetTokenInfo($tokenAddress: String!, $days: Int, $hours: Int) {
query GetTokenInfo($tokenAddress: String!, $days: Int, $hours: Int, $mins: Int) {
bundles(first: 10) {
ethPriceUSD
}
Expand Down Expand Up @@ -47,6 +47,14 @@ query GetTokenInfo($tokenAddress: String!, $days: Int, $hours: Int) {
volumeUSD
}
token5MinData(first: $mins, orderBy: periodStartUnix, orderDirection: desc) {
id
periodStartUnix
priceUSD # The price of the token in USD for the day
totalValueLockedUSD
volumeUSD
}
# Get all pools involving this token for liquidity details
whitelistPools {
id
Expand All @@ -70,15 +78,15 @@ export const pageTimePeriodAtom = atomWithStorage<TimePeriod>('tokenDetailsTimeP
function getQueryParams(timePeriod: any) {
switch (timePeriod) {
case 0:
return [2, 2];
return [2, 2, 12];
case 1:
return [2, 24];
return [2, 30, 2];
case 2:
return [2, 168];
return [2, 168, 2];
case 3:
return [2, 720];
return [2, 720, 2];
case 4:
return [365, 2];
return [365, 2, 2];
}
return [2, 2];
}
Expand All @@ -89,36 +97,55 @@ export default function TokenDetailsPage() {
const chain = validateUrlChainParam(chainName)
const isNative = tokenAddress === NATIVE_CHAIN_ID
const [timePeriod, setTimePeriod] = useAtom(pageTimePeriodAtom)
const [totalDays, totalHours] = getQueryParams(timePeriod);
const [totalDays, totalHours, total5Mins] = getQueryParams(timePeriod);
const [address, duration] = useMemo(
/* tokenAddress will always be defined in the path for for this page to render, but useParams will always
return optional arguments; nullish coalescing operator is present here to appease typechecker */
() => [isNative ? getNativeTokenDBAddress(chain) : tokenAddress ?? '', toHistoryDuration(timePeriod)],
[chain, isNative, timePeriod, tokenAddress]
)
const { data: tokenQuery } = useTokenQuery({
const { data: tokenQuery, refetch: refetchTokenQuery } = useTokenQuery({
variables: {
address,
chain,
},
pollInterval: 12000, // 12 seconds
})

const { data: tokenPriceQuery } = useTokenPriceQuery({
const { data: tokenPriceQuery, refetch: refetchTokenPriceQuery } = useTokenPriceQuery({
variables: {
address,
chain,
duration,
},
pollInterval: 12000, // 12 seconds
})

const { data: luxData, loading: luxLoading } = useQuery(GetTokenInfo, {
const { data: luxData, loading: luxLoading, refetch: refetchLuxData } = useQuery(GetTokenInfo, {
client: chainName == 'lux' ? luxNetClient : zooNetClient,
variables: {
tokenAddress: address,
days: totalDays,
hours: totalHours,
mins: total5Mins,
},
pollInterval: 12000, // 12 seconds
})

// Use effect to handle periodic refetching
useEffect(() => {
const intervalId = setInterval(() => {
refetchTokenQuery()
refetchTokenPriceQuery()
if (chainName === 'lux' || chainName === 'zoo') {
refetchLuxData()
}
}, 12000) // 12 seconds interval

// Clear interval on component unmount
return () => clearInterval(intervalId)
}, [refetchTokenQuery, refetchTokenPriceQuery, refetchLuxData, chainName])

if (luxLoading) {
console.log("Loading data...");
} else {
Expand All @@ -135,6 +162,20 @@ export default function TokenDetailsPage() {
const priceLow52W = dailyPrices && Math.min(...dailyPrices);
const token = luxData?.token;

// Use effect to handle periodic refetching
useEffect(() => {
const intervalId = setInterval(() => {
refetchTokenQuery()
refetchTokenPriceQuery()
if (chainName === 'lux' || chainName === 'zoo') {
refetchLuxData()
}
}, 12000) // 12 seconds interval

// Clear interval on component unmount
return () => clearInterval(intervalId)
}, [])

// Now, you can assign the JSON data to a variable of type TokenQuery
const transformedTokenDetail: TokenQuery = tokenPriceQuery ?? {
token: {
Expand Down Expand Up @@ -192,6 +233,11 @@ export default function TokenDetailsPage() {
timestamp: data.periodStartUnix,
value: parseFloat(data.priceUSD),
}))
const token5MinData = luxData?.token?.token5MinData.filter((data: any) => parseFloat(data.priceUSD) !== 0).map((data: any) => ({
id: `VGltZXN0YW1wZWRBbW91bnQ6MV8x${data.periodStartUnix}_VVNE`, // Encoded version of the timestamped amount
timestamp: data.periodStartUnix,
value: parseFloat(data.priceUSD),
}))

const transformedTokenPriceHistory: TokenPriceQuery = {
token: {
Expand All @@ -204,7 +250,7 @@ export default function TokenDetailsPage() {
id: "QW1vdW50OjFfVVNE", // Encoded amount ID
value: parseFloat(ethPriceUSD) * parseFloat(ethPrice),
},
priceHistory: timePeriod < 4 ? tokenHourData : tokenDayData,
priceHistory: timePeriod < 1 ? token5MinData : timePeriod < 4 ? tokenHourData : tokenDayData,
},
},
};
Expand Down
2 changes: 1 addition & 1 deletion src/tokens-lux/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ export const TOKENS_LUX_LIST = {
"name": "Zoo LUX",
"symbol": "ZLUX",
"decimals": 18,
"logoURI": "https://cdn.lux.network/exchange/icon-png/lux.png",
"logoURI": "https://cdn.lux.network/bridge/currencies/zoo/zlux.svg",
"extensions": {}
},
{
Expand Down

0 comments on commit 112e4b9

Please sign in to comment.