Skip to content

Commit

Permalink
Fix sticky user stats on leaderboard table
Browse files Browse the repository at this point in the history
  • Loading branch information
samchuk-vlad committed Jun 11, 2024
1 parent c81dbfc commit f31d794
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 105 deletions.
116 changes: 12 additions & 104 deletions src/modules/telegram/StatsPage/LeaderboardTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { LeaderboardDataPeriod } from '@/services/datahub/leaderboard/types'
import { useMyMainAddress } from '@/stores/my-account'
import { cx, mutedTextColorStyles } from '@/utils/class-names'
import Image from 'next/image'
import { useEffect, useMemo, useRef, useState } from 'react'
import { useMemo } from 'react'

const TABLE_LIMIT = 100

Expand Down Expand Up @@ -46,12 +46,7 @@ type Data = {
reward: string
}

const parseTableRows = (
data: Data[],
limit: number,
currentUserRank: Data,
ref?: any
) => {
const parseTableRows = (data: Data[], limit: number, currentUserRank: Data) => {
return (
data
.map((item) => ({
Expand All @@ -64,128 +59,42 @@ const parseTableRows = (
/>
),
className:
item.address === currentUserRank.address
? 'bg-slate-800 sticky top-[3.5rem] z-[2]'
: '',
rowRef: item.address === currentUserRank.address ? ref : null,
item.address === currentUserRank?.address ? 'bg-slate-800' : '',
}))
.slice(0, limit) || []
)
}

function createObserver(
boxElement: HTMLElement,
setElementintesecting: (isIntersecting: boolean) => void
) {
let observer

let options = {
root: null,
rootMargin: '0px 0px -8% 0px',
threshold: 1.0,
}

observer = new IntersectionObserver((entries) => {
entries.map((entry) => {
setElementintesecting(entry.isIntersecting)
})
}, options)
observer.observe(boxElement)
}

const LeaderboardTable = ({ period }: LeaderboardTableProps) => {
const myAddress = useMyMainAddress()

const { data: leaderboardDataResult, isLoading } =
leaderboardDataQueryByPeriod[period].useQuery(period)

const [isElementIntersecting, setIsElementIntersecting] = useState<
boolean | undefined
>()
const [initIsIntersection, setInitIsIntersection] = useState<
boolean | undefined
>(undefined)

const ref = useRef<HTMLDivElement>(null)

const { data: userStats } = userDataQueryByPeriod[period].useQuery(
myAddress || ''
)

const { rank, address, reward } = userStats || {}

const currentUserRank = useMemo(
() => ({
address: address || '',
rank: rank || null,
reward: reward || '0',
}),
[address, rank, reward]
)

const dataItems = useMemo(
() => (leaderboardDataResult as any[]) || [],
[leaderboardDataResult]
)

useEffect(() => {
if (ref.current) {
createObserver(ref.current, setIsElementIntersecting)
}
}, [])

useEffect(() => {
if (
initIsIntersection === undefined &&
isElementIntersecting !== undefined
) {
setInitIsIntersection(isElementIntersecting)
}
}, [initIsIntersection, isElementIntersecting])

const data = useMemo(() => {
const currentUserRankItem = currentUserRank.rank
const currentUserRankItem = userStats?.rank
? {
address: currentUserRank.address,
rank: currentUserRank.rank!,
address: userStats.address,
rank: userStats.rank!,
'user-role': (
<UserPreview
address={currentUserRank.address}
desc={<UserReward reward={currentUserRank.reward} />}
address={userStats.address}
desc={<UserReward reward={userStats.reward} />}
/>
),
className: cx(
'bg-slate-800 sticky top-[3.5rem] z-[2]',
'transition-opacity duration-100',
isElementIntersecting ? 'opacity-0' : 'opacity-100'
),
rowRef: null,
className: cx('bg-slate-800 sticky bottom-[4.8rem] z-[11]'),
}
: undefined

if (
currentUserRank &&
currentUserRank.rank &&
currentUserRank.rank > TABLE_LIMIT
) {
return [
currentUserRankItem,
...parseTableRows(dataItems || [], TABLE_LIMIT, currentUserRank),
]
}

return [
initIsIntersection !== undefined && !initIsIntersection
? currentUserRankItem
: undefined,
...parseTableRows(
dataItems || [],
TABLE_LIMIT,
currentUserRank,
ref || undefined
),
...parseTableRows(leaderboardDataResult || [], TABLE_LIMIT, userStats),
currentUserRankItem,
].filter(Boolean)
}, [currentUserRank, dataItems, isElementIntersecting, initIsIntersection])
}, [userStats, leaderboardDataResult])

return (
<>
Expand Down Expand Up @@ -215,7 +124,6 @@ const LeaderboardTable = ({ period }: LeaderboardTableProps) => {
return (
<TableRow
key={i}
rowRef={item?.rowRef}
columns={leaderboardColumns()}
item={item}
withDivider={false}
Expand Down
2 changes: 1 addition & 1 deletion src/services/datahub/leaderboard/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ const GET_USER_DATA_BY_WEEK = gql`
query GetUserDataByWeek($address: String!, $timestamp: String!) {
activeStakingAddressRankByTotalRewardsForPeriod(
args: {
period: ALL_TIME
period: WEEK
address: $address
withReward: true
timestamp: $timestamp
Expand Down

0 comments on commit f31d794

Please sign in to comment.